解析 CSS 样式表
Parsing a CSS stylesheet
我目前正在为一个学习项目编写一个简单的HTML渲染器,但目前被困在解析部分 - 我知道有点早。我采用了"不要重新发明轮子"的方法,并使用TinyXML来解析HTML文件。虽然绘画有点遥远,但我计划使用OpenGL。但是,我遇到了CSS解析器部分缺少轮子的问题。是否有任何小型且相当快速的 CSS 解析器库可用?如果是,有人可以指出我吗?如果不是这种情况 - 任何人都可以给我一个简短的解释,说明自己使用 C++ 解析 CSS 文件的方法是什么?例如,我是否使用正则表达式?
所以,总结一下:
- 是否有任何用 C/C++ 编写的小型/快速 CSS 解析器库可用?
- 如何使用正则表达式解析一个非常简单的 CSS 文件(例如)?
我绝不想包含整个CSS标准,现在只需要标准的"by-id","by-class"和"by-tag"CSS选择器就足够了。我期待着一些可能对我的追求有所帮助的东西:D
我会使用LibCSS,只要不重新发明轮子。这是一件好事。LibCSS包含一个解析和选择API,这使得将其与HTML解析器相结合变得简单。
但是,如果在哪里谈论学习项目,编写解析器也是一件好事。我建议深入研究递归体面的解析器。这些实现起来相当简单。
如果我用伪C++代码编写一个简单的解析器,它看起来像:
enum Type {
ID, // #
CLASS, // .
IDENTIFIER, // [a-zA-Z][a-zA-Z0-9-_]
LWING, // {
RWING, // }
COLON, // :
SEMI, // ;
}
struct Token {
std::string value;
Type type;
}
bool has_next_token();
bool has_next_token(Type type);
Token next_token();
Token expect_token(Type type) {
Token token = next_token();
if (token.type != type) {
std::runtime_error("Error: expected another type");
}
}
void parse() {
while (has_next_token()) {
parse_rule();
}
}
void parse_rule() {
parse_selector();
expect_token(Type.LWING);
while (!has_next_token(Type.RWING)) {
parse_assignment();
}
expect_token(Type.RWING);
}
void parse_selector() {
if (has_next_token(Type.CLASS)) {
parse_class();
} else if (has_next_token(Type.ID)) {
parse_id();
} else {
parse_tag();
}
}
void parse_class() {
expect_token(Type.CLASS);
Token token = expect_token(Type.IDENTIFIER);
std::string class_name = token.value;
// Do something with class_name
}
void parse_id(); // Almost the same as parse_class
void parse_tag(); // You know the drill
void parse_assignment() {
expect(Type.IDENTIFIER);
expect(Type.COLON);
parse_value();
expect(Type.SEMI);
}
void parse_value(); // I'll leave this one to you