c - 如何使用 yacc 解析 if /else 语句
问题描述
我正在尝试创建一个 .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 是 ':'。但是当我编译我的文件时,我得到了以下错误;
'ifstatement' 的 $4 没有声明类型 ifstatement:IF 表达式冒号语句 {if($2==true){$$ = $4;}}
所以,我的问题是除了{if($2==true){$$ = $4;}}之外的 if else 语句我应该使用什么规则?
解决方案
bison 抱怨的问题是您分配给$$
,这是 的语义值ifstatement
,但您没有告诉 bison 的类型ifstatement
是什么。就像在 C 中一样,如果你有一个变量,你需要声明它的类型。
这假定您已经告诉 bison 并非所有语法符号都具有相同的类型。换句话说,您有一个%union
声明,它为您正在使用的所有不同类型指定标签名称。%token
然后,您需要声明所有具有 using和%type
声明值的标记和非终结符的类型。
您的操作if($2==true){$$ = $4;}
要求$$
( ifexpression
)、$2
( expression
) 和$4
( statement
) 都已声明类型。如果野牛只抱怨其中一个,那么您知道如何声明类型,因为已经声明了其他两个。否则,如果你有很多这样的错误,那么你应该查看野牛手册中的相关部分。您可能还想阅读有关语义值的整章。
但是,以上都没有解决该操作的真正问题,这与您解释程序代码的方法有关。如果条件实际上为真,if
则期望语句仅评估其分支。true
但是请注意$4
,无论条件是否为真,在执行您的操作之前已经计算了 的值。该操作所做的只是将已经计算的 值转发statement
到 的值中ifstatement
。另外,请注意,$$
如果条件为 ,则未分配任何内容false
。所以它的值要么是 of$4
要么是未初始化的,在后一种情况下,尝试使用它的值将是未定义的行为。
这就是为什么在解析期间无法评估任何非平凡语言的原因。条件块只能在条件语句被解析后才能评估,因此需要推迟它们的评估。重复的块——for
例如while
语句——必须被多次评估,尽管它们只被解析一次。
推荐阅读
- node.js - 错误:Route.post() 需要一个回调函数,但得到一个 [object Undefined],不知道如何继续
- python - 反转python的元音变音编码以规范化文本或以当前形式规范化
- php - 5张表之间的Laravel关系
- python - Python 等效于 Javascript Object.values() 方法
- python - 如何获取 Sagemaker 实例 CPU 利用率
- node.js - NodeJS & RxJS:将 observables 转换为 nodeJs 流
- regex - bash 中的正则表达式量词——简单与扩展匹配 {n} 次
- excel - Excel中的范围加法和乘法
- python - 尝试对 .csv 数据集进行 linregress 时,Scipy.stats 错误“要解压的值太多”
- azure - 使用 Terraform 配置 Azure 媒体服务:特别是使用 Widervine DRM 的内容密钥策略