Bison 野牛的延迟语义行为?

Bison 野牛的延迟语义行为?,bison,Bison,例如,我对操作有以下语法: StmtList: Stmt | StmtList Stmt ; Stmt: StmtOne { ActionOne } | StmtTwo { ActionTwo } ; 问题是ActionOne应该在Action2之前完成(出于某种原因),但是用户可以按任意顺序写入StmtOne和StmtTwo。你知道怎么做吗?我曾经想过,但不确定它是否有效。这类问题的一般解决方案是: 使用生成的解析器构建AST 执行AST并根

例如,我对操作有以下语法:

StmtList: Stmt
        | StmtList Stmt
        ;

Stmt: StmtOne { ActionOne }
    | StmtTwo { ActionTwo }
    ;

问题是ActionOne应该在Action2之前完成(出于某种原因),但是用户可以按任意顺序写入StmtOne和StmtTwo。你知道怎么做吗?我曾经想过,但不确定它是否有效。

这类问题的一般解决方案是:

  • 使用生成的解析器构建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; }
           ;
    

    您在语法中使用了交替运算符(管道)。这意味着只有
    StmtOne
    StmtTwo
    是有效的
    Prog
    ,而不是两者都有效。这就是你的意思吗?我修改了语法以澄清我的意图,很抱歉搞混了。对于我简单的语法来说,构建AST有点过火,尽管它是正确的方法。我选择多次解析文本,并使用一些技巧使操作有序。