- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当我对以下文件运行 parser.y 时,出现以下错误:
myanalyzer.y: warning: 14 nonterminals useless in grammar
myanalyzer.y: warning: 36 rules useless in grammar
myanalyzer.y:7.8-18: fatal error: start symbol main_struct does not derive any sentence
我不明白代码有什么问题:
%{
#include <stdio.h>
#include <string.h>
extern int line_num;
extern char *yytext;
%}
%start main_struct
%left PLUS
%token PUBLIC 1
...
%token CONSTANT_CHAR 45
%%
main_struct:variables_declaration
class_declaration
functions_declaration
;
constant: INT
|BOOLEAN
|CHAR
|STRING
|FLOAT
|DOUBLE
;
locality: PUBLIC
| PRIVATE
;
identifier1: IDENTIFIER
| identifier1 COMMA IDENTIFIER
;
class_body: /*empty*/
| locality variables_declaration locality functions_declaration identifier1
| locality variables_declaration identifier1
| locality functions_declaration identifier1
| identifier1
;
variables_declaration: /*empty*/
| variables_declaration constant identifier1 SEMICOLON
| variables_declaration constant identifier1 COMMA
;
class_declaration: /*empty*/
| class_declaration CLASS identifier1 BEGIN class_body END
;
functions_declaration: functions_declaration constant identifier1 LEFT_PARENTHESIS vars_in_func RIGHT_PARENTHESIS BEGIN function_body END
| functions_declaration VOID identifier1 LEFT_PARENTHESIS vars_in_func RIGHT_PARENTHESIS BEGIN function_body END
;
vars_in_func: /*empty*/
| constant identifier1
| vars_in_func COMMA constant identifier1
;
function_body: /*empty*/
| variables_declaration identifier1
| identifier1
;
%%
int main ()
{
if ( yyparse() == 0 && error==0){
printf("Accepted\n");
}
else{
printf("Rejected\n");
}
}
我现在是第一次使用 Bison,所以代码可能不太好,但我想编译它以便开始测试。但是我该如何解决这个错误呢?
注意:我可以简单地做到这一点:
main_struct:variables_declaration
| class_declaration
| functions_declaration
;
但这是错误的,因为我希望我的程序拥有所有 3 个声明。
最佳答案
functions_declaration
没有非递归产生式,不像 variables_declaration
和 class_declaration
都有空产生式。如果没有非递归产生式,就不可能从非终结符中推导出一个句子,因为推导永远不会终止。
由于没有句子可以匹配 functions_declaration
,main_struct
也无法匹配,这反过来使所有非终结符都变得无用。
写重复非终结符有两种常见的模式,分别对应正则表达式运算符*
(0个或多个)和+
(1个或多个):
optional_repeating_element: /* EMPTY */
| optional_repeating_element element
;
repeating_element : element
| repeating_element element
;
请注意,这些仅在基本情况下有所不同。在这两种情况下,您都需要为单个 元素
单独定义一个产生式。所以在你的情况下,你可以使用:
functions_declaration: function
| functions_declaration function
;
function: constant identifier1 LEFT_PARENTHESIS vars_in_func RIGHT_PARENTHESIS
BEGIN function_body END
| VOID identifier1 LEFT_PARENTHESIS vars_in_func RIGHT_PARENTHESIS
BEGIN function_body END
;
三个注意事项:
1) 不要手动给你的代币编号。 Bison 会为您做这件事,而且结果更易于维护。此外,对于单个字符的终端使用单引号字符通常更具可读性;这些终端不需要声明,你可以使用一个简单的默认 flex 规则来处理所有这些终端(。{return *(unsigned char*)yytext;}
。)就这样了更简单,无论是写还是读。
2) 您对 vars_in_func
的定义将接受一些您可能不想接受的句子。你拥有的是:
vars_in_func: /*empty*/
| constant identifier1
| vars_in_func COMMA constant identifier1
;
由于 vars_in_func
可以为空(第一个产生式),第三个产生式允许 vars_in_func
以 COMMA
开头,因此以下将是有效:
(, int foo)
要正确执行此操作,您需要将空参数列表情况与递归分开。
3) 您对 identifier1
(对于标识符列表来说这是一个相当困惑的名称)的使用会给您带来麻烦。您允许函数声明声明一个名称列表,但是有限前瞻与声明一个名称列表的变量声明无法区分。考虑以下两个句子:
int variable1, variable2, variable3;
int function1, function2, function3() BEGIN END
当解析器找到第一个,
时,它无法知道后面是整数变量列表,还是具有相同参数和主体的函数列表。我猜你并不是真的想让第二种情况成为可能,这意味着你不应该在 functions_declaration
(或 class_declaration
)。即使在您的参数列表非终端 (vars_in_func
) 中,您也有一些奇怪的东西,但可以解析; vars_in_func
是一个以逗号分隔的类型列表,后跟以逗号分隔的名称列表,因此以下是合法的:
void function(int a, b, int c, d)
也许你是有意的,但我不相信。
关于bison - fatal error : does not derive any sentence,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23827656/
我有一个使用 Yacc 编写的语法。语法的相关部分摘录在这里 postfix : primary | postfix '[' expr ']' | postfix '[' ex
如何在 bison/yacc 中使用继承的属性? 说,我有这样的语法 - 程序 -> stmts 我想做的是在 Bison 身上: 程序:stmts {$$.next = newLabel(); $1
有什么方法可以更改 Bison 错误消息的格式?例如,不要说 syntax error, unexpected T_ID, expected ';' or T_IMPORT说 unexpected i
我的语法有这两个标记声明: %token RP %token ELSE 而这两条规则: Statement : IF LP Exp RP Statement; Statement : IF LP
如果有一个表单的输入文件: BEGIN stuff.... END BEGIN stuff ... END 我的 .y 文件是这样的 %token BEGIN %token END %star
我希望为现有语言创建一个 JavaScript 解析器,该语言目前具有笨拙的“手工制作”C# 和 Java 解析器。我想使用 Jison,并且也一直在尝试学习 Bison 的基础知识。 我不确定如何回
目前我正在研究一个源到源编译器,我已经编写了一个野牛解析器,可以正确地为输入创建 AST。我现在需要对语法树进行多次转换,因此我需要向树中插入许多节点。 我可以手动创建所有要添加到语法树中的结构体/联
如果有一个表单的输入文件: BEGIN stuff.... END BEGIN stuff ... END 我的 .y 文件是这样的 %token BEGIN %token END %star
我正在寻找为现有语言创建 JavaScript 解析器的方法,该语言目前具有笨拙的“手工制作”C# 和 Java 解析器。想用Jison,也在努力学习Bison的基础。 一个我不确定如何回答的问题是
我正在使用 flex/bison 编写解析器(我可以用 Python 编写解析器,但我总是更喜欢经典。) 当我用这个编译代码时: gcc -lfl -ly chance.tab.c lex.yy.c
正在使用 flex/bison 开发编译器。我的构建输出中有此警告。 警告:在默认操作中键入冲突 ('s' '') 请问有什么帮助吗? 最佳答案 它似乎与源中的 %token 和 %type 声明有关
考虑这个 lex.l 文件: %{ #include "y.tab.h" %} digit [0-9] letter [a-zA-Z] %% "+"
我正在为 bison 中的一个简单的 Pascal 编译器编写语法,我想可视化我在 pascal.y 中指定的语法的解析树。是否可以基于我的 pascal.y 文件以图形方式显示语法树? 最佳答案 野
我正在尝试编写一个能够使用以下输入的语法: begin #this is a example x = 56; while x > 0 do begin point 15
我正在尝试使用 BNF 语法编写 Flex/Bison 文件。但是,当我尝试编译时出现错误,而且我不确定如何调试它们。 BNF语法: ::= | head() ::=:: | @ | tail() |
我正在用 Flex/Bison 编写一个小程序来标记/解析我创建的查询语言。 我想知道是否有任何方法可以在 Flex/Bison 中创建任何关键字。 我的意思是:flex 将输入分解成一个标记列表,但
我正在尝试使用 flex 和 bison 创建过滤器,因为我想从复杂的语言中获取某些语法元素。我的计划是使用 flex + bison 来识别语法,并转储出感兴趣元素的位置。 (然后使用脚本根据转储的
我正在尝试实现一个可以进行浮点运算的 Flex/bison 计算器。我的 Flex 代码如下所示 %{ #include "calc.tab.h" #include void yyerror(cha
我正在尝试使用 FLEX 和 BISON 进行一些练习。 这是我写的代码: calc_pol.y %{ #define YYSTYPE double #include "calc_pol.tab.h"
我有一个使用括号和方括号作为分隔符的语法。当由 bison 生成的解析器输入带有不平衡分隔符的输入时,传递给 yyerror 的 YYLTYPE* 中的错误位置是输入的结尾。所以,例如,在输入 x
我是一名优秀的程序员,十分优秀!