C ++中的符号规范(语法)解析器(也许使用Spirit?)

时间:2014-05-09 17:40:13

标签: c++ parsing boost boost-spirit

我正在尝试为C ++中的符号规范编写一个小而简单的解析器。我首先尝试使用Yacc / Bison(我已经知道)和ANTLR等工具,但这些工具对于我想做的事情来说太过笨拙和复杂。

我的语言有以下二元运算符: = (规范), + (总和),(产品);和以下一元运算符: Seq (表达式的序列), Z(###)(可以编号的单位元素)和E(###) (中性元素,也可以编号)。它还应包含变量。我认为总和和产品的约束优先权应该是标准的优先级。

以下是规则系统的示例:

A = Seq B
B = Z(1) + Z(2).Z(2).C
C = E(1) + Z(4).Z(4).B

我想解析为关联映射,将表达式树(Seq B)索引到变量名(A)。

经过几次辅助尝试(例如使用Python),我已经确定了一个理想的工具,即Boost Library中的Spirit。我想在代码中更紧密地集成一些东西。以下StackOverflow提供了我需要的大部分元素:

Boolean expression (grammar) parser in c++

然而,Spirit非常复杂,而且我对我不熟悉库使用的高级C ++特性这一事实并没有帮助 - 或者事实上,我不确定如何纠正编译器给出的错误。我的最新尝试:

https://gist.github.com/anonymous/354bb84e54042a3b54f3

它不会编译。即使它确实如此,我也不确定我是如何操纵解析结构的。我不确定自己是否走在正确的轨道上。

有人可以帮助重新开始吗?或者建议另一种合理的解决方案?

更新1:以下是对我想要的内容的更准确描述。

规则列表

"VAR = EXPR"

EXPR在哪里:

EXPR :=  EXPR + EXPR
      |  EXPR . EXPR
      |  Seq EXPR
      |  Z<digits*>       (defaults to zero if not placed)
      |  E<digits*>       (defaults to zero if not placed)
      |  VAR

VAR  := alnum+     (excludes Z## and E##)

例如:

PP = Z + L1 . R1 + L2 . R2 + L3 . R3 + Seq Z3 . Seq Z4
L1 = Z10.Z9
R1 = Z12.PP + E4
...

会给我一个关联表:

[ "PP" -> parsing tree that I can navigate for (Z + L1...)
  "L1" -> parsing tree for ... 
]

PP是:

PP = (((((Z + (L1 . R1)) + (L2 . R2)) + (L3 . R3))) + ((Seq Z3) . (Seq Z4)))

我应该说cv_and_he的调试已经非常有用了,但是: - 我不确定我的语法是否正确; - 我不知道如何从方程组中解析列表; - 我不知道如何在解析树后利用/导航解析树。

我的目标是编写遍历树的递归函数并进行相应的模拟。

更新2:我设法完成了大部分解析:

https://gist.github.com/anonymous/b6a63a1aa5caa6461dd6

我想知道它是否正确,或者我是否错过了一个错误。在那之后,我无法弄清楚的是: - 如何最好地解析这些规则的列表(而不仅仅是一个); - 如何遍历解析的规则,并修改状态(例如,我想重新编号变量,并将每个变量与一个始终相同的整数相关联 - lambda重新编号)。

更新3:我想我现在的部分问题是:如何让“静态访问者”不是静态的,即如何使其具有可修改的状态。 / p>

更新4:我在这里找到了对最后一个问题的答案:

How can I use the boost visitor concept with a class containing state variables?

我想知道这是否是一个合理的解决方案。我仍然想知道解析规则列表的最佳方法是什么。

0 个答案:

没有答案