我有一个无上下文语法(CFG)。我想编写一个c ++代码来做与CFG相同的事情。
是否有任何内置功能或简单的转换方式? 或者,有什么可以执行CFG?
答案 0 :(得分:1)
您可能希望查看bison
,即yacc
的GNU实现,它代表yet another compiler compiler
,并将根据您提供的语法生成解析器。< / p>
答案 1 :(得分:1)
没有这样的C ++内置,但你有几个选择。
解析器生成器:Flex + Bison允许您以(LA)LR或GLR形式从语法描述中生成C或C ++中的解析器。如果您对CFG有很好的把握,那么学习Bison语法将很容易。 Bison和Flex将输出C代码,但它们可以在语义操作中优雅地处理C ++。
自上而下的解析器:如果你的语法是LL(k)形式,并且你不想学习额外的语言,那么你可以很容易地从你的语法中推导出一个递归下降解析器。这很快,但LL不如(G)LR强大,如果你不是非常小心所有边缘情况,那么手写解析器很快就会成为一场噩梦。 LL解析器也可以实现为表解析器(如LR),但是手工编辑表迟早会变得混乱。
Bison也可以发出C ++类而不是函数,只需添加:
%skeleton "lalr1.cc"
%language "c++"
%define parser_class_name {Parser}
致序。唯一的区别是,现在令牌是枚举的成员而没有更多定义,因此您必须使用Parser::token::TOKEN_NAME
而不是TOKEN_NAME
。
另外,Flex可能会被扼杀......制作一个C ++类,但是将Bison C ++和Flex C ++点击在一起并不是一件非常简单的事情,值得单独提问。
答案 2 :(得分:1)
您正在寻找parser generators(有时称为编译器编译器)。您已经了解bison
。您可以尝试使用ANTLR3(或ANTLR4获取Java)。这是comparison。
此外,一些解析器是手写的recursive descent ones,(例如GCC,请参阅this)
请注意,context-free grammar是规范,用于某些正式语法(您可以在某些解析器中实现)。但semantics和pragmatics也很重要。
答案 3 :(得分:1)
另一种方法是使用boost::spirit
- 纯C ++解决方案制作解析器,但需要依赖Boost