c++ - 解析 CSS 样式表

标签 c++ css regex parsing

我目前正在为一个学习元素编写一个简单的 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 解析器的结合变得简单。

但是,如果我们正在谈论学习元素,那么编写解析器也是一件好事。我建议深入研究 recursive decent parsers 。这些实现起来相当简单。

如果我用伪 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

关于c++ - 解析 CSS 样式表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35848032/

相关文章:

c++ - 我可以在 C++ 中全局声明类对象吗?

c++ - CLang Libtooling:获取 clang::VarDecl、clang::FieldDecl 或 clang::ParmVarDecl 内变量的数据类型

html - 使用CSS绘制向右箭头

html - SendGrid "helping"我在保存时更改我的 html 模板?

regex - 使用 VIM 替换命令将对象的所有字段用引号引起来

html - 正则表达式在另一个标签中查找标签

c++ - 再次 double 四舍五入

php - preg_replace() 标签名称

regex - R dplyr : rename variables using string functions

c++ - 如何在 Lua 中处理 C++ 类构造函数失败