如何使用 yacc 解析 if /else 语句

How to parse if /else statements with yacc

我正在尝试创建一个 .y 文件来设计基本编程语言,其中终端值只是 true 和 false。但是,我很难为 if 语句定义规则。 if 语句的语法是;

a=TRUE
if TRUE: print(a)

我的 BNF 就像;

statement : assignment | ifstatement | print
ifstatement : IF expression COLON statement                {if(==true){$$ = ;}}

其中 IF 是关键字 if 的标记,“:”的 COLON。但是当我编译文件时,出现以下错误;

of ‘ifstatement’ has no declared type ifstatement : IF expression COLON statement {if(==true){$$ = ;}}

所以,我的问题是除了 {if($2==true){$$ = $4;}}[=22= 之外,我应该对 if else 语句使用什么规则] ?

bison 抱怨的问题是你给 $$ 赋值,这是 ifstatement 的语义值,但是你没有告诉 bison [=11= 的类型是什么] 是。就像在 C 中一样,如果你有一个变量,你需要声明它的类型。

这假定您已经告诉 bison 并非所有文法符号都具有相同的类型。换句话说,您有一个 %union 声明,它指定了您正在使用的所有不同类型的标签名称。然后您需要使用 %token%type 声明来声明所有具有值的标记和非终端的类型。

您的操作 if(==true){$$ = ;} 要求 $$ (ifexpression)、</code> (<code>expression) 和 </code> (<code>statement) 都有声明的类型。如果 bison 只抱怨其中一个,那么您知道如何声明类型,因为其他两个已经声明。否则,如果您有很多这样的错误,那么您应该查看 relevant section in the bison manual. You might want to also read the entire chapter on semantic values.

但是,上面的 none 解决了该操作的真正问题,这与您解释程序代码的方法有关。如果条件实际上为真,则 if 语句预计仅评估其 true 分支。但是请注意 </code> 的值在您的操作执行之前就已计算完毕,无论条件是否恰好为真。该操作所做的只是将 <code>statement 的已计算值转发到 ifstatement 的值。另请注意,如果条件为 false,则不会为 $$ 分配任何内容。所以它的值要么是 </code> 的值,要么是未初始化的,在后一种情况下,尝试使用它的值将是未定义的行为。</p> <p>这就是为什么在解析期间无法评估任何重要语言的原因。条件块只有在条件语句被解析后才能被求值,所以它们的求值需要被推迟。并且重复的块——例如 <code>forwhile 语句——尽管它们只被解析一次,但必须被计算多次。