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

问题描述 投票:0回答:1

我试图创建一个.y文件来设计基本的编程语言,其中终端值只是真和假。但是,我很难为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是':'的标记。但是当我编译我的文件时,我得到以下错误;

$ if of'ifstatement'没有声明类型if语句:IF表达式COLON语句{if($ 2 == true){$$ = $ 4;}}

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

c parsing token yacc lex
1个回答
3
投票

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

这假设您告诉Bison并非所有语法符号都具有相同的类型。换句话说,您有一个%union声明,它为您使用的所有不同类型指定标记名称。然后,您需要使用%token%type声明声明所有具有值的标记和非终端的类型。

你的行动if($2==true){$$ = $4;}要求$$ifexpression),$2expression)和$4statement)都声明了类型。如果bison只抱怨其中一个,那么你知道如何声明类型,因为已经声明了其他两个。否则,如果您有许多此类错误,那么您应该查看relevant section in the bison manual。您可能还想阅读有关semantic values的整个章节。

但是,以上都没有解决该操作的实际问题,这与您解释程序代码的方法有关。如果条件实际上是真的,那么if声明只会评估其true分支。但是请注意,在执行动作之前已经计算了$4的值,无论条件是否恰好。该动作所做的就是将已经计算出的statement值转换为ifstatement的值。此外,请注意,如果条件是$$false没有分配任何东西。所以它的值要么是$4的值,要么是未初始化的,而在后一种情况下,尝试使用它的值将是未定义的行为。

这就是在解析过程中无法评估任何非平凡语言的原因。只有在解析条件语句后才能评估条件块,因此需要延迟它们的评估。重复的块 - 例如forwhile语句 - 必须多次评估,尽管它们只被解析一次。

© www.soinside.com 2019 - 2024. All rights reserved.