我有以下语法(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_translated
和word_not_translated
完全相同,所以语法太复杂,应该简化为一个word
。增加复杂性的唯一原因是行动可能不同。
这是解决这种情况的唯一方法吗?这是处理这种情况的野牛的最佳做法吗?
答案 0 :(得分:1)
语义操作最好从任何编译器或解释器中的解析树执行。如果你试图从野牛规则行动中执行语言语义动作指导,你将总是遇到你所描述的那种混乱。
只需在野牛行动中构建一个解析树,然后在知道完整树后采取适当的语义动作来走树。大多数标准编译器文本都有工作示例。
答案 1 :(得分:-1)
我将恭敬地不同意Brian的断言,野牛行动应该仅用于构建一个解析树,然后在解析之后,树应该走路,在此期间,应该采取真正的行动。否则,一个“总会陷入混乱”。
如果是这样,经典的O'Reilly yacc文本就不会说:“通常动作代码会构建一个对应于 输入,以便以后的代码可以处理整个语句甚至整个语句 一次编程“。而不是”经常“它会说”总是“。
然而,Brian的回答非常有用,在尝试理解它时,我不得不阅读。然后我发现恕我直言,我的问题正确答案,因为它已发布。为了未来的浏览器,我会发布答案。
恕我直言,正确的方法是使用$0
。在我的帖子中使用原始语法,该操作的伪代码将是:
if ($0 is meaningful)
$$ = $1
else
$$ = translate($1)