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

标签 c parsing token yacc lex

我正在尝试创建一个 .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 的标记,“:”的 COLON。但是当我编译我的文件时,我得到了以下错误;

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

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

最佳答案

bison提示的问题是你给$$赋值,这是ifstatement的语义值,但是你还没有告诉bison是什么类型ifstatement 是。就像在 C 中一样,如果您有一个变量,则需要声明它的类型。

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

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

但是,以上都没有解决该操作的真正问题,这与您解释程序代码的方法有关。如果条件实际上为真,则if 语句预计仅评估其true 分支。但是请注意,无论条件是否为真,$4 的值在您的操作执行之前就已计算完毕。该操作所做的只是将 statement 的已计算值转发到 ifstatement 的值中。另外请注意,如果条件为 false,则不会为 $$ 分配任何内容。所以它的值要么是 $4 的值,要么是未初始化的,在后一种情况下,尝试使用它的值将是未定义的行为。

这就是为什么在解析期间无法评估任何重要语言的原因。条件 block 只有在条件语句被解析后才能被求值,所以它们的求值需要被推迟。重复的 block ——例如 forwhile 语句——尽管它们只被解析一次,但它们必须被计算多次。

关于c - 如何使用 yacc 解析 if/else 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55563335/

相关文章:

c - 如何在C中使用printf和scanf读写文件?

c - OpenGL 球形相机 : cube rendering incorrectly

android - Twitter 登录 Quickblox

c - 你好。我的程序总是无法创建我期望的字符串输出。你能注意到一个缺陷吗?

c - 为什么 Visual Studio 2015 找不到 libxml2 的文件依赖项 iconv.h?

python - 我正在使用电话号码模块来验证电话号码。它运行良好,但我只需要国家号码作为输出

javascript - 解析 Django 中 querydict 字典中的整个列表

java - 哪个面向 Java 的词法分析器用于简单项目(ANTLR、DIY 等)

php - Laravel 5.1 session 中 POST header token 和 token 之间的 token 不匹配

oauth - Google 验证 ID token 的完整性 gettirn 错误 : IllegalArgumentException