gpt4 book ai didi

bison - fatal error : does not derive any sentence

转载 作者:行者123 更新时间:2023-12-02 07:29:19 27 4
gpt4 key购买 nike

当我对以下文件运行 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_declarationclass_declaration 都有空产生式。如果没有非递归产生式,就不可能从非终结符中推导出一个句子,因为推导永远不会终止。

由于没有句子可以匹配 functions_declarationmain_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_funcCOMMA 开头,因此以下将是有效:

(, 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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com