我正在尝试创建一个 .y 文件来设计基本编程语言,其中终端值只是 true 和 false。但是,我很难为 if 语句定义规则。 if语句的语法是这样的;
a=TRUE
if TRUE: print(a)
我的 BNF 就像;
statement : assignment | ifstatement | print
ifstatement : IF expression COLON statement {if($2==true){$$ = $4;}}
其中 IF 是关键字 if 的标记,“:”的 COLON。但是当我编译我的文件时,我得到了以下错误;
$4 of ‘ifstatement’ has no declared type ifstatement : IF expression COLON statement {if($2==true){$$ = $4;}}
所以,我的问题是除了 {if($2==true){$$ = $4;}} 之外,我应该对 if else 语句使用什么规则?
最佳答案
bison提示的问题是你给$$
赋值,这是ifstatement
的语义值,但是你还没有告诉bison是什么类型ifstatement
是。就像在 C 中一样,如果您有一个变量,则需要声明它的类型。
这假定您已经告诉 bison 并非所有文法符号都具有相同的类型。换句话说,您有一个 %union
声明,它为您正在使用的所有不同类型指定标签名称。然后,您需要使用 %token
和 %type
声明来声明所有具有值的标记和非终端的类型。
您的操作 if($2==true){$$ = $4;}
要求 $$
(ifexpression
), $2
(expression
) 和$4
(statement
) 都有声明的类型。如果 bison 只提示其中一个,那么您知道如何声明类型,因为其他两个已经声明。否则,如果你有很多这样的错误,那么你应该查看 relevant section in the bison manual .您可能还想阅读有关 semantic values 的整章内容.
但是,以上都没有解决该操作的真正问题,这与您解释程序代码的方法有关。如果条件实际上为真,则if
语句预计仅评估其true
分支。但是请注意,无论条件是否为真,$4
的值在您的操作执行之前就已计算完毕。该操作所做的只是将 statement
的已计算值转发到 ifstatement
的值中。另外请注意,如果条件为 false
,则不会为 $$
分配任何内容。所以它的值要么是 $4
的值,要么是未初始化的,在后一种情况下,尝试使用它的值将是未定义的行为。
这就是为什么在解析期间无法评估任何重要语言的原因。条件 block 只有在条件语句被解析后才能被求值,所以它们的求值需要被推迟。重复的 block ——例如 for
和 while
语句——尽管它们只被解析一次,但它们必须被计算多次。
关于c - 如何使用 yacc 解析 if/else 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55563335/