如何最好地处理野牛中同一规则的不同动作?
How to best handle varying actions for the same rule in bison?
我有以下语法(SSCCE):
%token WORD
%%
program : word word
;
word : WORD // have to translate only for first word
;
规则 word : WORD
应该具有以下作用,即 WORD
的标记语义值适合于 "translated" 左侧的语义值,前提是规则 program: word 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
.增加复杂性的唯一原因是操作可以不同。
这是唯一的方法吗?这是 bison 处理这种情况的最佳做法吗?
语义操作最好从任何编译器或解释器中的解析树执行。如果您尝试从野牛规则操作中执行语言语义操作方向,您将总是陷入您所描述的那种混乱。
只需在 bison 动作中构建一个解析树,然后在知道完整的树后采取适当的语义动作遍历树。大多数标准编译器文本都有工作示例。
我非常不同意 Brian 的断言,即 bison 动作应该只用于构建解析树,然后在解析之后,应该遍历树,在此期间,应该采取真正的动作。或者,一个 "always gets into the kind of mess"。
如果是这样,经典的 O'Reilly yacc 文本就不会说:“通常操作代码会构建一个对应于
输入,以便后面的代码可以处理整个语句甚至整个
一次编程”。而不是 "often" 它会说 "always"。
但是,Brian 的回答非常有用,因为在试图理解它的同时,我不得不阅读。然后我发现恕我直言,我的问题的正确答案是 posted。我会 post 为了未来浏览器的利益而回答。
恕我直言,正确的方法是使用 [=11=]
。使用我 post 中的原始语法,该操作的伪代码将是:
if ([=10=] is meaningful)
$$ =
else
$$ = translate()
我有以下语法(SSCCE):
%token WORD
%%
program : word word
;
word : WORD // have to translate only for first word
;
规则 word : WORD
应该具有以下作用,即 WORD
的标记语义值适合于 "translated" 左侧的语义值,前提是规则 program: word 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
.增加复杂性的唯一原因是操作可以不同。
这是唯一的方法吗?这是 bison 处理这种情况的最佳做法吗?
语义操作最好从任何编译器或解释器中的解析树执行。如果您尝试从野牛规则操作中执行语言语义操作方向,您将总是陷入您所描述的那种混乱。
只需在 bison 动作中构建一个解析树,然后在知道完整的树后采取适当的语义动作遍历树。大多数标准编译器文本都有工作示例。
我非常不同意 Brian 的断言,即 bison 动作应该只用于构建解析树,然后在解析之后,应该遍历树,在此期间,应该采取真正的动作。或者,一个 "always gets into the kind of mess"。
如果是这样,经典的 O'Reilly yacc 文本就不会说:“通常操作代码会构建一个对应于 输入,以便后面的代码可以处理整个语句甚至整个 一次编程”。而不是 "often" 它会说 "always"。
但是,Brian 的回答非常有用,因为在试图理解它的同时,我不得不阅读。然后我发现恕我直言,我的问题的正确答案是 posted。我会 post 为了未来浏览器的利益而回答。
恕我直言,正确的方法是使用 [=11=]
。使用我 post 中的原始语法,该操作的伪代码将是:
if ([=10=] is meaningful)
$$ =
else
$$ = translate()