Parsing 解析DECF时出现问题(变量声明与构造函数)
我正在使用bison(3.0.4)和lexer来实现Decaf编程语言的(部分)语法。我只是在实现课堂上的东西 因此,我的任务很简单:将每个产生式规则(作为字符串)存储在树中,然后打印出来 例如,如果您有以下代码行作为输入Parsing 解析DECF时出现问题(变量声明与构造函数),parsing,bison,yacc,context-free-grammar,bisonc++,Parsing,Bison,Yacc,Context Free Grammar,Bisonc++,我正在使用bison(3.0.4)和lexer来实现Decaf编程语言的(部分)语法。我只是在实现课堂上的东西 因此,我的任务很简单:将每个产生式规则(作为字符串)存储在树中,然后打印出来 例如,如果您有以下代码行作为输入 class Foo{Foo(intarg1){some2a;}} 您(必须)获得以下输出 <ClassDecl> --> class identifier <classBody> <ClassBody>
class Foo{Foo(intarg1){some2a;}}
您(必须)获得以下输出
<ClassDecl> --> class identifier <classBody>
<ClassBody> --> { <VariableDecl>* <ConstructorDecl>* <MethodDecl>* }
<ConstructorDecl> --> identifier ( <ParameterList> ) <Block>
<ParameterList> --> <Parameter> <, Parameter>*
<Parameter> --> <Type> identifier
<Type> --> <SimpleType>
<SimpleType> --> int
<Block> --> { <LocalVariableDecl>* <Statement>* }
<LocalVariableDecl> --> <Type> identifier ;
<Type> --> <SimpleType>
<SimpleType> --> identifier
下面是完整的.y文件的示例。基本问题是
constructor\u declmore
可以为空,并且var\u decl
和constructor\u decl
都可以以ID
开头
这是一个问题,因为在解析器能够识别构造函数\u decl
之前,它需要减少一个(空的)构造函数\u declmore
。但它显然无法做到这一点,除非它知道var_declmore
已经完成
因此,当它看到一个ID
时,它必须在以下两种操作中选择一种:
constructor\u declmore
,从而决定不再有var\u decl
s;或ID
,以开始解析新的var\u decl
Foo
是启动var_decl
的ID
,导致您注意到的错误消息
还应注意语法产生的reduce/reduce冲突。它来自
方法declmore:method decl
规则,它与创建方法declmore
的其他可能方式相冲突,即从空的方法declmore
开始,然后添加方法decl基本问题是构造函数declmore
可以为空,而且var\u decl
和constructor\u decl
都可以以ID
开头
这是一个问题,因为在解析器能够识别构造函数\u decl
之前,它需要减少一个(空的)构造函数\u declmore
。但它显然无法做到这一点,除非它知道var_declmore
已经完成
因此,当它看到一个ID
时,它必须在以下两种操作中选择一种:
减少一个空的constructor\u declmore
,从而决定不再有var\u decl
s;或
移动ID
,以开始解析新的var\u decl
在没有优先声明的情况下(这在这里没有帮助),bison/yacc总是解决移位/减少冲突,以支持移位操作。因此,在本例中,它假设Foo
是启动var_decl
的ID
,导致您注意到的错误消息
还应注意语法产生的reduce/reduce冲突。它来自method\u declmore:method\u decl
规则,它与创建method\u declmore
的另一种可能方式相冲突,即从一个空的method\u declmore
开始,然后添加一个method\u decl,我从该文件中得到大量警告。包括两班制,减少冲突;一是减少冲突;还有关于无用规则的警告。顺便说一句,如果你省略了动作,阅读语法会容易得多;你会看到很多警告,因为诸如表达式、名称和new_表达式之类的规则还没有被使用。它们在语句规则中使用,该规则尚未实现,因为我想找出该规则的问题(vardecl和构造函数冲突)。如果只使用适用的规则创建一个语句,您会发现这要容易得多。我从该文件中得到了大量警告。包括两班制,减少冲突;一是减少冲突;还有关于无用规则的警告。顺便说一句,如果你省略了动作,阅读语法会容易得多;你会看到很多警告,因为诸如表达式、名称和new_表达式之类的规则还没有被使用。它们在语句规则中使用,该规则尚未实现,因为我想找出该规则的问题(vardecl和构造函数冲突)。如果您只使用适用的规则创建一个语句,您会发现这要容易得多。没错。但是,当我更改classBody的规则时,现在它尝试匹配构造函数的decl规则,尽管我给出了变量声明。检查编辑。@alwaysone:回答问题后,请不要更改。若你们有一个新问题,单独问它。它并没有解决我关于类主体定义的问题,所以这个问题并没有得到完全的回答。我不会彻底改变它,因为正确声明类主体的问题仍然存在。它回答了您的问题。它并没有解决你语法上的所有问题。无论如何,它解决了一个并不罕见的问题,因此它本可以帮助其他人,但问题不再显示问题,对未来的访问者来说毫无用处。可能有人有相同的规则(语法),但想象一下,如果有人检查了这个答案,但它并没有完全得到回答,因为其中一条规则的问题仍然存在。因此,我改变问题并不重要,因为在这两种情况下它都不起作用,因为它仍然不起作用。你在一个方向上帮了很多忙,而且只在一个更大问题的一个子问题上帮了忙,我至少问了一个方向。简言之,你帮助了一件事,然而,主要问题仍然存在。这是真的。但是,当我更改classBody的规则时,现在它尝试匹配构造函数的decl规则,尽管我给出了变量声明。检查编辑。@alwaysone:回答问题后,请不要更改。如果你
class_decl:
CLASS ID LC class_body RC
;
/* FIXME: Gotta add more grammar here */
class_body: var_declmore constructor_declmore method_declmore
| var_declmore constructor_declmore
| var_declmore method_declmore
| constructor_declmore method_declmore
| method_declmore
| var_declmore
| constructor_declmore
| %empty
;
var_declmore: var_decl
| var_declmore var_decl
;
constructor_declmore: constructor_decl
| constructor_declmore constructor_decl
;
var_decl: type ID SEMICOLON
| type ID error
;
constructor_decl: ID LP parameter_list RP block
| ID error parameter_list RP block
;