如何最好地处理野牛中同一规则的不同行为?

时间:2016-11-16 10:44:03

标签: parsing bison

我有以下语法(SSCCE):

%token  WORD
%%
program     : word  word
            ;

word        : WORD  // have to translate only for first word
            ;

规则word : WORD应该具有以下操作:WORD的令牌语义值适当地"翻译"至于左侧的语义值,仅当它是规则word中的第一个program: word word时。

在野牛中做这件事的最佳做法是什么?

我不知道如何通过行动来做到这一点。我必须将语法本身扩展到:

%token  WORD
%%
program     : word_translated   word_not_translated
            ;

word_translated     : WORD  { // translate }
            ;

word_not_translated  : WORD { // do not translate }
            ;
好的,但是这个我不喜欢。因为,就语法而言,语法有两个符号word_translatedword_not_translated完全相同,所以语法太复杂,应该简化为一个word 。增加复杂性的唯一原因是行动可能不同。

这是解决这种情况的唯一方法吗?这是处理这种情况的野牛的最佳做法吗?

2 个答案:

答案 0 :(得分:1)

语义操作最好从任何编译器或解释器中的解析树执行。如果你试图从野牛规则行动中执行语言语义动作指导,你将总是遇到你所描述的那种混乱。

只需在野牛行动中构建一个解析树,然后在知道完整树后采取适当的语义动作来走树。大多数标准编译器文本都有工作示例。

答案 1 :(得分:-1)

我将恭敬地不同意Brian的断言,野牛行动应该仅用于构建一个解析树,然后在解析之后,树应该走路,在此期间,应该采取真正的行动。否则,一个“总会陷入混乱”。

如果是这样,经典的O'Reilly yacc文本就不会说:“通常动作代码会构建一个对应于 输入,以便以后的代码可以处理整个语句甚至整个语句 一次编程“。而不是”经常“它会说”总是“。

然而,Brian的回答非常有用,在尝试理解它时,我不得不阅读。然后我发现恕我直言,我的问题正确答案,因为它已发布。为了未来的浏览器,我会发布答案。

恕我直言,正确的方法是使用$0。在我的帖子中使用原始语法,该操作的伪代码将是:

if ($0 is meaningful)
    $$ = $1
else
    $$ = translate($1)