Compiler construction 忽略yacc中的匹配生产

Compiler construction 忽略yacc中的匹配生产,compiler-construction,bison,yacc,Compiler Construction,Bison,Yacc,在使用GNUbison时,是否可以在匹配产品后不执行任何操作,然后检查是否可以使用其他规则来减少相同的令牌序列?基本上,我所寻找的与此类似: iexpr: VARIABLE { if (condition) { /*some action */ } else { /*pushback read symbol, and check if other

在使用GNUbison时,是否可以在匹配产品后不执行任何操作,然后检查是否可以使用其他规则来减少相同的令牌序列?基本上,我所寻找的与此类似:

iexpr: VARIABLE { if (condition) {
                    /*some action */
                  }
                  else {
                    /*pushback read symbol, and check if other pattern can
                         be matched */
                  }
                }
 fexpr: VARIABLE {   }

感谢您,您应该能够使用YYBACKUP功能来完成此操作。

您可以使用--一个执行回溯的yacc变体来完成此操作:

iexpr: VARIABLE [ if (!condition)
                     /* this parse was wrong, backtrack and try something else */
                    YYERROR; ]
                { /* some action */ }
fexpr: VARIABLE { /* some other action */  }
但正如评论者所指出的,试图在解析器中进行类型检查是一个坏主意,只会导致不必要的复杂语法和糟糕的、令人困惑的类型错误错误消息

相反,只需为所有类型的表达式使用单个(一组)的
expr
规则,并在生成的解析树上进行单独的类型检查。您甚至不需要构建整个解析树并将其保留下来;您可以构建一小段解析树并立即进行类型检查,然后在进一步解析之前丢弃不需要的信息。比如:

expr: expr '+' expr {
    Typecheck('+', $1, $3); /* make sure operand types are appropriate for an add */
    $$ = BuildBinopCode('+', $1, $2); /* build some code to add two things */
}

我很想知道你是如何得到这个要求的。我不知道野牛有这样的设施。如果控件正在执行您的代码,这意味着bison已经为您匹配了模式。即使您以某种方式破解了它并试图实现您的目标,bison最终也会在下一次迭代中匹配相同的规则。我建议正确定义语法。“如果你告诉我你在分析什么,我也许能帮你。”Ashishmahamoni:我基本上同意你的评估。我不能回答这个问题,但是在一个上下文中,类似的东西可能很有用,那就是在一个详细的语言(SQL)中,您希望允许将关键字用作标识符。我看到过一些被操纵的东西,因此当检测到错误时,如果令牌当前是关键字,则使用标识符的令牌类型而不是关键字来重试语法。这一点出人意料地好;还有一些地方你会遇到麻烦。请用正确的术语。这些是产品,而不是“模式”。@AshishMahamuni正在尝试创建一个具有严格类型的解释器。因此,整数表达式(iexpr)和浮点表达式(fexpr)都可以从变量派生,具体取决于变量的类型。@EJP已更正。谢谢你指出了怎么做?例子?