我正在尝试为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?
我想知道这是否是一个合理的解决方案。我仍然想知道解析规则列表的最佳方法是什么。