有没有比lex / flex更好(更现代)的工具来生成C ++的分词器?

我最近添加的源文件parsing到一个现有的工具,从复杂的命令行参数生成输出文件。

命令行参数非常复杂,我们开始允许将它们作为一个被parsing的文件来提供,就好像它是一个非常大的命令行一样,但是语法仍然很尴尬。 所以我添加了使用更合理的语法parsing源文件的function。

我使用flex 2.5.4 for windows来为这个自定义源文件格式生成标记器,并且它工作。 但我讨厌的代码。 全局variables,奇怪的命名约定,以及它生成的c ++代码都很糟糕。 现有的代码生成后端被粘贴到flex的输出 – 我不使用yacc或野牛。

我即将回到那个代码,我想使用一个更好/更现代的工具。 有谁知道的东西。

  • Windows命令提示符运行(Visual Studio集成是好的,但我使用make文件来构build)
  • 生成一个适当的封装的C ++ tokenizer。 (没有全局variables)
  • 使用正则expression式来描述标记规则(与lex语法兼容)
  • 不要强迫我使用c-runtime(或伪造它)来读取文件。 (从内存中parsing)
  • 当我的规则强制令牌生成器回溯(或自动修复)时警告我
  • 给我完全控制variables和方法名称(所以我可以符合我现有的命名约定)
  • 允许我将多个parsing器链接到单个.exe,而不会发生名称冲突
  • 如果需要,可以生成UNICODE(16位UCS-2)parsing器
  • 不是一个集成的标记器+parsing器生成器(我想要一个lexreplace,而不是一个lex + yaccreplace)

如果这是唯一可用的,我可能会生活在一个只生成标记化表的工具中。

Solutions Collecting From Web of "有没有比lex / flex更好(更现代)的工具来生成C ++的分词器?"

Ragel: http : //www.complang.org/ragel/它适合你的大部分要求。

  • 它在Windows上运行
  • 它没有声明变量,所以你可以把它们放在一个类中,或者放在一个函数里面。
  • 它有很好的工具来分析正则表达式,看看他们什么时候回溯。 (我不知道这一点,因为我从来没有使用Ragel中的语法来创建一个回溯解析器。)
  • 变量名称不能更改。
  • 表名以机器名为前缀,并且声明为“常量静态”,所以你可以在同一个文件中放入多个文件,并且在同一个程序中有多个同名文件(只要它们是在不同的文件中)。
  • 您可以将变量声明为任何整数类型,包括UChar(或任何您喜欢的UTF-16类型)。 它不会自动处理代理对。 它没有Unicode的特殊字符类(我认为)。
  • 它只是正则表达式…没有野牛/ YACC功能。

它产生的代码对程序的干扰很小。 代码也非常快,而且Ragel语法比我见过的任何语言都更加灵活和可读。 这是一个坚实的软件。 它可以生成一个表驱动解析器或一个goto驱动解析器。

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

Flex也有一个C ++输出选项。
结果是一组解析的类。

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

%option C++ %option yyclass="Lexer" 

然后在你的源代码是:

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

有两个工具可以想到,虽然你需要找出适合自己的Antlr和GoldParser 。 在这两种工具中都可以使用语言绑定,将其插入到C ++运行时环境中。

boost.spirit和Yard解析器出现在我的脑海里。 请注意,使用词法生成器的方法在某种程度上被C ++内部DSL(特定于域的语言)所取代以指定令牌。 仅仅因为它是你的代码的一部分而不使用外部工具,只需遵循一系列规则来指定你的语法。

你可以试试http://www.benhanson.net/lexertl.html 。 这是一个只有头文件的库,允许你在运行时建立一个词法分析器(非常快)。 它具有flex的大部分功能,并且具有广泛的字符。

问候,