是否有比lex/flex更好(更现代)的工具来为C++生成标记化器?

Joh*_*ler 22 c++ windows lex tokenize

我最近添加了源文件解析到现有工具,该工具从复杂的命令行参数生成输出文件.

命令行参数变得如此复杂以至于我们开始允许它们作为一个被解析的文件提供,就像它是一个非常大的命令行一样,但语法仍然很尴尬.所以我添加了使用更合理的语法解析源文件的功能.

我使用flex 2.5.4 for windows为这个自定义源文件格式生成了tokenizer,并且它有效.但我讨厌代码.全局变量,奇怪的命名约定以及它生成的c ++代码非常糟糕.现有的代码生成后端粘在flex的输出上 - 我不使用yacc或bison.

我即将重新回到代码中,我想使用更好/更现代的工具.有谁知道的东西.

  • 在Windows命令提示符下运行(Visual Studio集成是可以的,但我使用make文件来构建)
  • 生成适当的封装C++标记生成器.(没有全局变量)
  • 使用正则表达式来描述标记化规则(与lex语法兼容)
  • 不强迫我使用c-runtime(或伪造它)进行文件读取.(从记忆中解析)
  • 当我的规则强制令牌器回溯(或自动修复)时警告我
  • 让我完全控制变量和方法名称(所以我可以符合我现有的命名约定)
  • 允许我将多个解析器链接到单个.exe而不会发生名称冲突
  • 如果我愿意,可以生成UNICODE(16位UCS-2)解析器
  • 不是集成的tokenizer +解析器生成器(我想要更换lex,而不是lex + yacc替换)

如果这是唯一可用的东西,我可能会使用刚生成标记化表的工具.

Die*_*Epp 11

Ragel:http://www.complang.org/ragel/它符合您的大多数要求.

  • 它在Windows上运行
  • 它不会声明变量,因此您可以根据需要将它们放在类中或函数内.
  • 它有很好的工具来分析正则表达式,看看它们何时会回溯.(我不太了解这一点,因为我从未在Ragel中使用会创建回溯解析器的语法.)
  • 变量名称无法更改.
  • 表名以机器名为前缀,并且它们被声明为"const static",因此您可以在同一个文件中放置多个,并在一个程序中具有多个具有相同名称(只要它们是在不同的文件中).
  • 您可以将变量声明为任何整数类型,包括UChar(或您喜欢的任何UTF-16类型).但是,它不会自动处理代理对.它也没有Unicode的特殊字符类(我认为).
  • 它只做正则表达式...没有野牛/ yacc功能.

它生成的代码对程序的干扰很小.代码也非常快,Ragel语法比我见过的任何东西都更灵活,更易读.它是一块坚如磐石的软件.它可以生成表驱动的解析器或goto驱动的解析器.


Tro*_*nic 6

Boost.Spirit.Qi(解析器 - 标记化器)或Boost.Spirit.Lex(仅限标记器).我绝对喜欢Qi,Lex也不错,但我只是倾向于采取Qi来满足我的解析需求......

Qi的唯一真正缺点往往是编译时间的增加,并且它的运行速度也比手写的解析代码稍慢.但它通常比使用正则表达式解析要快得多.

http://www.boost.org/doc/libs/1_41_0/libs/spirit/doc/html/index.html


t0m*_*13b 5

有想到的两个工具,但是你需要找出自己这将是合适的,ANTLR的GoldParser.两种工具都提供了语言绑定,可以将其插入到C++运行时环境中.


Mar*_*ork 5

Flex还有一个C++输出选项.
结果是一组进行解析的类.

只需将以下内容添加到lex文件的头部:

%option C++
%option yyclass="Lexer"
Run Code Online (Sandbox Code Playgroud)

然后在你的来源中它是:

std::fstream  file("config");
Lexer         lexer(&file)
while(int token = lexer.yylex())
{
}
Run Code Online (Sandbox Code Playgroud)

  • 由于你没有保留所产生的代码,因此其惊人的细节是无关紧要的.您的源文件是lex文件.只要代码工作不会污染全局命名空间,实现细节就是无关紧要的.注意1:不构建源文件只构建目标文件和标题(即立即删除源).使对象和lex文件之间的依赖关系不是源文件.注意:它们是messey因为它有效. (2认同)