例如,我的操作语法如下:
StmtList: Stmt
| StmtList Stmt
;
Stmt: StmtOne { ActionOne }
| StmtTwo { ActionTwo }
;
问题是ActionOne应该在ActionTwo之前完成(出于某种原因),但用户可以按任何顺序编写StmtOne和StmtTwo。有关如何做到这一点的任何想法?我曾经想过Command pattern,但不确定它是否有效。
答案 0 :(得分:2)
这类问题的一般解决方案是:
使用生成的解析器构建AST
行走AST并根据需要执行操作。
实际上,这会延迟所有操作,直到整个解析完成,此时所有信息都已知;此外,步行可以按照您认为方便或必要(或甚至多次)的任何顺序进行。
我认为这是命令模式的一个实例。我说这是一个编译模式的实例,这是bison
的设计目的。但是,与其他一些解析器生成器不同,bison
不能为AST构建提供简写符号。
这是一个概念性的例子:
prog : actions { do_action1($1->action1); do_action2($1->action2); }
actions: %empty { $$ = actionLists(); }
| actions action1 { append($1->action1, $2); $$ = $1; }
| actions action2 { append($1->action2, $2); $$ = $1; }
;