我正在尝试创建一个.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和':'的冒号的标记。但是当我编译文件时,出现以下错误;
“ ifstatement”的$ 4没有声明的类型ifstatement:IF表达式COLON语句{if($ 2 == true){$$ = $ 4;}}
所以,我的问题是,除 {if($ 2 == true){$$ = $ 4;}} 以外的if else语句应该用于什么规则?
>答案 0 :(得分:3)
bison抱怨的问题是您要分配给$$
的语义值ifstatement
,但是您没有告诉bison ifstatement
的类型是什么。就像在C中一样,如果您有一个变量,则需要声明它的类型。
假设您已经告诉野牛并不是所有的语法符号都具有相同的类型。换句话说,您有一个%union
声明,它为所使用的所有不同类型指定标签名称。然后,您需要使用%token
和%type
声明来声明所有具有值的令牌和非终结符的类型。
您的操作if($2==true){$$ = $4;}
要求$$
(ifexpression
),$2
(expression
)和$4
(statement
)全部都有声明的类型。如果野牛只抱怨其中的一种,那么您知道如何声明类型,因为另外两种已经声明过了。否则,如果您有许多此类错误,则应查看relevant section in the bison manual。您可能还需要阅读semantic values上的整个章节。
但是,上述方法均不能解决该操作的实际问题,这与您解释程序代码的方法有关。实际上,如果条件为真,则if
语句仅会评估其true
分支。但是请注意,$4
的值已经在执行操作之前就已经计算了,无论条件是否为真。该动作所做的全部工作就是将statement
的已计算值转发到ifstatement
的值中。另外,请注意,如果条件为$$
,则false
不会被分配任何内容。因此,其值要么是$4
的值,要么未初始化。在后一种情况下,尝试使用其值将是不确定的行为。
这就是为什么在解析期间无法评估任何非平凡的语言的原因。条件块只能在条件语句解析后才能求值,因此需要推迟对它们的求值。重复的块(例如for
和while
语句)尽管必须解析一次,但必须进行多次评估。