2016-03-20 2 views
0

Я пытаюсь написать компилятор с BNFC. Я собираюсь использовать BNFC для генерации абстрактного дерева синтаксиса. Но я получаю ошибки для них, и я не могу понять, почему. На нем, похоже, не много документации.BNFC Bad Coercion в правиле

Вот ошибки я получаю:

Bad coercion in rule _. Prog ::= Block 
Bad coercion in rule _. Declarations ::= Declaration ";" Declarations 
Bad coercion in rule _. Declarations ::= 
Bad coercion in rule _. Declaration ::= Var_declaration 
Bad coercion in rule _. Declaration ::= Fun_declaration 
Bad coercion in rule _. Type ::= "int" 
Bad coercion in rule _. Type ::= "real" 
Bad coercion in rule _. Type ::= "bool" 
Bad coercion in rule _. Array_dimensions ::= "[" Expr "]" Array_dimensions 
Bad coercion in rule _. Array_dimensions ::= 
Bad coercion in rule _. Fun_block ::= Declarations Fun_body 
Bad coercion in rule _. Param_list ::= "(" Parameters ")" 
Bad coercion in rule _. Parameters ::= Basic_declaration More_parameters 
Bad coercion in rule _. Parameters ::= 
Bad coercion in rule _. More_parameters ::= "," Basic_declaration More_parameters 
Bad coercion in rule _. More_parameters ::= 
Bad coercion in rule _. Basic_declaration ::= Ident Basic_array_dimensions ":" Type 
Bad coercion in rule _. Basic_array_dimensions ::= 
Bad coercion in rule _. Program_body ::= "begin" Prog_stmts "end" 
Bad coercion in rule _. Fun_body ::= "begin" Prog_stmts "return" Expr ";" "end" 
Bad coercion in rule _. Prog_stmts ::= Prog_stmt ";" Prog_stmts 
Bad coercion in rule _. Prog_stmts ::= 
Bad coercion in rule _. Identifier ::= Ident Array_dimensions 
Bad coercion in rule _. Expr ::= Bint_term 
Bad coercion in rule _. Bint_term ::= Bint_factor 
Bad coercion in rule _. Bint_factor ::= Int_expr Compare_op Int_expr 
Bad coercion in rule _. Bint_factor ::= Int_expr 
Bad coercion in rule _. Int_expr ::= Int_expr Addop Int_term 
Bad coercion in rule _. Int_expr ::= Int_term 
Bad coercion in rule _. Int_term ::= Int_term Mulop Int_factor 
Bad coercion in rule _. Int_term ::= Int_factor 
Bad coercion in rule _. Int_factor ::= "(" Expr ")" 
Bad coercion in rule _. Modifier_list ::= "(" Arguments ")" 
Bad coercion in rule _. Modifier_list ::= Array_dimensions 
Bad coercion in rule _. Arguments ::= Expr More_arguments 
Bad coercion in rule _. Arguments ::= 
Bad coercion in rule _. More_arguments ::= "," Expr More_arguments 
Bad coercion in rule _. More_arguments ::= 

Вот пример файла BNFC:

_.Prog ::= Block; 

M_Prog. Block ::= Declarations Program_body; 

_.Declarations ::= Declaration ";" Declarations; 
_. Declarations ::= ; 

_. Declaration ::= Var_declaration; 
_. Declaration ::= Fun_declaration; 

M_Var. Var_declaration ::= "var" Ident Array_dimensions ":" Type; 

_. Type ::= "int"; 
_. Type ::= "real"; 
_. Type ::= "bool"; 

_. Array_dimensions ::= "[" Expr "]" Array_dimensions; 
_. Array_dimensions ::=; 

M_Fun. Fun_declaration ::= "fun" Ident Param_list ":" Type "{" Fun_block "}"; 

_. Fun_block ::= Declarations Fun_body; 

_. Param_list ::= "(" Parameters ")"; 

_. Parameters ::= Basic_declaration More_parameters; 
_. Parameters ::= ; 

_. More_parameters ::= "," Basic_declaration More_parameters; 
_. More_parameters ::= ; 

_. Basic_declaration ::= Ident Basic_array_dimensions ":" Type; 

_. Basic_array_dimensions ::= "[" "]" Basic_array_dimensions; 
_. Basic_array_dimensions ::=; 

Это, кажется, что я использую _. ярлык неправильно. Но в руководстве есть только строка или две, описывающие ее использование. Что я здесь делаю неправильно?

+2

Не может помочь с документацией. Предложите, чтобы вы попытались получить грамматику с правилами 1-2, чтобы передать «bnfc» перед тем, как попробовать что-то большое, и сравните свой результат с любыми примерами грамматики, которые вы можете найти. (Мнение: если у вас плохо документированный инструмент, я бы выбрал еще один инструмент. Вы выбрали генератор синтаксиса для удобства и сэкономили бы время, верно?). –

ответ

1

documentation От:

Подчеркивания, конечно, имеет смысл только в качестве заменителей одного аргумента конструкторов, где тип значения совпадает с типом аргумента.

Это означает, что вы можете использовать только _ если у вас есть ровно один нетерминал в правой части правила, и что нетерминал такое же, как и на левом сайте. Таким образом, вы можете сделать что-то вроде _. A ::= "(" A ")" ; , но не _. A ::= "(" B ")" ; или _. A ::= "(" A A ")" ;.

В вашем примере я предлагаю вам дать ярлык каждому правилу, _ в основном используется для упрощения АСТ в некоторых угловых случаях.

BTW есть также ярлык синтаксиса для lists of things.

Смежные вопросы