如何使用 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>for
和 while
语句——尽管它们只被解析一次,但必须被计算多次。
我正在尝试创建一个 .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>for
和 while
语句——尽管它们只被解析一次,但必须被计算多次。