无法弄清楚为什么 Bison 抛出“由于冲突,规则在解析器中无用”

2024-05-11

我正在为一种非常简单的编程语言编写 BNF 语法,并使用 Flex 和 Bison 进行编译。
我只有 3 种变量和常量类型:实数、整数、字符串.
我的 .l 文件具有“ID”的标记定义,如下所示:

DIGIT [0-9]
LETTER [a-zA-Z]
ID {LETTER}({LETTER}|{DIGIT})*


我的 .y 文件有一个定义标识符像这样:

identifier:
ID;

现在,我想使用标识符定义来构建变量和常量名称。但我也想限制对相同类型数据的赋值(例如,我不希望将字符串分配给整数变量)。所以我创建了一些规​​则来区分每种变量和常量:

id_variable_string:
identifier;

id_variable_integer:
identifier;

id_variable_real:
identifier;

我对常量做了同样的事情。 现在,在我的语言中,我有一个用于常量声明/定义的部分,然后是一个用于变量声明的部分。也就是说,常量在赋值的同时声明(类似于“myConstant = 123”),但必须首先声明变量,然后在专门为语句设计的部分中赋值。
例如,如果我想要一个整数和一个字符串变量,我必须首先声明它们:
STRING myStrVariable;
整数 myIntVariable;
然后,在为语句保留的区域中,我可以选择进行赋值(语句可以是赋值、决策、选择、输出等):

assignment: 
        id_variable_string ASSIGN_OPERATOR literal_string
        | id_variable_string ASSIGN_OPERATOR id_const_string 
        | id_variable_string ASSIGN_OPERATOR id_variable_string 
        | id_variable_string ASSIGN_OPERATOR concatenacion  
        | id_variable_integer ASSIGN_OPERATOR id_const_integer 
        | id_variable_integer ASSIGN_OPERATOR id_variable_integer  
        | id_variable_integer ASSIGN_OPERATOR expression 
        | id_variable_integer ASSIGN_OPERATOR literal_integer
        | id_variable_real ASSIGN_OPERATOR id_variable_real
        | id_variable_real ASSIGN_OPERATOR id_const_real
        | id_variable_real ASSIGN_OPERATOR expression
        | id_variable_real ASSIGN_OPERATOR literal_real
        ;

我在这里的目的是明确指出,字符串变量只能分配给字符串文字、字符串串联(使用 +)、字符串常量或另一个字符串变量。对于整数变量和实数变量来说都是一样的,只是它们不能被分配一个串联,而是一个表达式(数学运算)。
串联定义如下:

concatenation:
        id_variable_string ADD_OPERATOR id_variable_string 
        | id_variable_string ADD_OPERADOR literal_string 
        | literal_string ADD_OPERADOR id_variable_string 
        | literal_string ADD_OPERADOR literal_string
        | id_const_string ADD_OPERADOR id_const_string  
        | id_const_string ADD_OPERADOR id_variable_string 
        | id_const_string ADD_OPERADOR literal_string 
        | literal_string ADD_OPERADOR id_const_string  
        | id_variable_string ADD_OPERADOR id_const_string
        ;

表达式定义为:

expression: 
        expression ADD_OPERATOR term
        | expression SUBST_OPERADOR term
        | term
        ;

term:
        term MULTIP_OPERATOR factor
        | term DIVISION_OPERATOR factor
        | factor
        ;

factor:     
        id_variable_integer
        | id_variable_real
        | id_const_integer
        | id_const_real
        | literal_integer
        | literal_real
        | PARENTHESIS_OPEN expression PARENTHESIS_CLOSE
        ;

现在,这就是 Bison 所说的:


55 赋值:id_variable_integer ASSIGN_OPERATOR id_const_integer
56 | 56 id_variable_integer ASSIGN_OPERATOR id_variable_integer
58 | 58 id_variable_integer ASSIGN_OPERATOR 文字_整数
59 | 59 id_variable_real ASSIGN_OPERATOR id_variable_real
60| id_variable_real ASSIGN_OPERATOR id_const_real
62 | 62 id_variable_real ASSIGN_OPERATOR 文字_real


状态 50 冲突:1 次转移/减少
状态 76 冲突:14 移/减
状态 130 冲突:2 次转移/减少
状态 131 冲突:1 次转移/减少
状态 133 冲突:1 次转移/减少
状态 134 冲突:1 次转移/减少
状态 135 冲突:1 次转移/减少
状态 137 冲突:1 次转移/减少
状态 138 冲突:1 次转移/减少


我假设我的语法中有一些错误,但我不确定到底是什么。


你说:

所以我创建了一些规​​则来区分每种变量和常量:

id_variable_string:
identifier;

id_variable_integer:
identifier;

id_variable_real:
identifier;

这就是你的问题。没有任何语法可以区分id_variable_string从一个id_variable_integer,所以你有(至少两个)浪费的规则。这就是它所抱怨的。它不知道什么时候得到identifier是否应该将其视为id_variable_string or an id_variable_integer.

您必须以不同的方式处理类型冲突 - 语义检查(而不是语法检查),以确保与标识符关联的类型与表达式中其他标识符的类型一致。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

无法弄清楚为什么 Bison 抛出“由于冲突,规则在解析器中无用” 的相关文章

  • 使用 Flex 和 Bison 编译时未定义对“_yyerror”的引用

    我正在尝试为迷你 Pascal 语言制作一个编译器 我为此使用了 Flex 和 Bison 并且出现了这个错误 我的 Flex 文件 include y tab h include
  • 任何能够处理左递归的 PEG 解析器? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 嗯 我知道可以重写语法来消除左递归 但这是一个非常无聊的过程 有时保持正确的关联性是非常不平凡的 是否有
  • C++:0.和0.0之间的区别?

    我很清楚之间的区别0 and 0 0 整数和双精度 但这之间有什么区别吗0 and 0 0 请注意 预先非常感谢 Axel 没有区别 两个文字都是双精度的 来自 C 语法 fractional constant digit sequence
  • 从flex+bison输出AST到main.cpp

    免责声明 虽然我已经完成了本教程 但我是一名 flex bison 菜鸟 http ds9a nl lex yacc cvs lex yacc howto html http ds9a nl lex yacc cvs lex yacc ho
  • 用于计算上下文无关语法的 FIRST 和 FOLLOW 集的算法 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我需要一种算法来计算语法的 FIRST 和 FOLLOW 集 是否有一个简单的算法或简单的代码来计算这些 大多数编译器教科书和解析算法
  • 野牛规格和优先顺序

    给定 Bison 规范 right TOK ADD TOK MUL 我想知道 TOK ADD 和 TOK MUL 的优先顺序是什么 另外如果我有野牛规格 left TOKMUL TOKADD left TOKDIV left TOKSUB
  • 表示语法中的语句终止换行符?

    许多编程语言都有以行结束符终止的语句 不过 通常情况下 如果解析器无法理解该行 则在语句中间允许使用行结束符 例如 a 3 4 将在 Ruby 和 Python 中解析为语句a 3 4 since a 3 没有任何意义 换句话说 换行符被忽
  • 语法:自上而下和自下而上的区别? (例子)

    这是来自的后续问题语法 自上而下和自下而上的区别 https stackoverflow com questions 3181960 grammar difference between a top down and bottom up 我
  • 删除 DCG 中的左递归 - Prolog

    我在这个语法中遇到了一个关于左递归的小问题 我正在尝试用 Prolog 编写它 但我不知道如何删除左递归
  • 在哪里可以找到 MATLAB 的形式语法?

    我想编写一个词法分析器生成器 将 MATLAB 语言的基本子集转换为 C C 等 为了帮助我做到这一点 我想找到一个包含 MATLAB 形式语法的文档 花了一些时间调查这一点 Mathworks 似乎没有提供这一点 有谁知道我在哪里可以找到
  • 转换为乔姆斯基范式

    我确实需要你的帮助 我有这些作品 1 A gt aAb 2 A gt bAa 3 A gt 我应该应用乔姆斯基范式 CNF 为了应用上述规则 我应该 消除 产生式 消除单一生产 删除无用的符号 我立即陷入困境 原因是 A 是一个可为空的符号
  • 不使用左手递归解析布尔表达式

    我正在尝试匹配这个 f some thing something else f 某物 是一个函数调用 它是一个表达式 是一个布尔运算符 别的东西 是一个字符串 也是一个表达式 所以布尔表达式应该是 expression operator e
  • Flex/Bison IDE? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个良好的开发环境 可以在 Flex 或 Bison 或两者上工作 是否有任何 IDE 具有
  • Rust 的词法语法是规则的、上下文无关的还是上下文相关的?

    大多数编程语言的词法语法都相当缺乏表达力 无法快速对其进行词法分析 我不确定 Rust 的词法语法属于什么类别 大多数看起来很正常 可能除了原始字符串文字 https doc rust lang org reference tokens h
  • 如何将 lex 文件中的 yytext 传递给 yacc?

    请我面临一个简单的问题 这就是问题 在我的 lex 文件中 我有类似的内容 char ptr String name BEGIN sName
  • 为什么这个 c# 代码片段是合法的?

    愚蠢的问题 但是为什么下面的行会编译 int i new int 1 正如您所看到的 我没有输入第二个元素并在那里留下了逗号 即使您希望它不会编译 仍然可以编译 我想是因为 ECMA 334 标准说 array initializer va
  • Epsilon(ε) 产生式以及 LR(0) 语法和 LL(1) 语法

    在很多地方 例如在这个答案中here https stackoverflow com a 8496838 7571421 我看到有人说 LR 0 语法不能包含 产生式 Also in 维基百科 https en wikipedia org
  • ANTLR“无法启动调试器。等待连接到远程解析器超时。”

    我在 AntlrWorks 中运行的 ANTLR 语法之一抛出 无法启动调试器 等待连接到远程解析器超时 过去 此消息通常会消失 但此消息会持续存在 在搜索 ANTLR 列表时 例如http www antlr org pipermail
  • Flex,连续扫描流(来自套接字)。我是否错过了使用 yywrap() 的某些内容?

    使用 Flex 进行模式识别 在基于套接字的扫描仪 连续流 上工作 Flex 找不到与 数组边界 重叠的匹配项 所以我实现了 yywrap 来设置新的数组内容 一旦 yylex 检测到 它将调用 yywrap 到目前为止还没有成功 基本上
  • 用PLY解析python,如何编码缩进和缩进部分

    我试图用 PLY 解析 python 语言的函数定义 我遇到了与缩进相关的问题 例如 对于 for 语句 我希望能够知道块何时结束 我在这里阅读了python语法 http docs python org 2 reference gramm

随机推荐