2016-03-20 4 views
0

Ich versuche, einen Compiler mit BNFC zu schreiben. Ich werde BNFC verwenden, um den abstrakten Syntaxbaum zu generieren. Aber ich bekomme Fehler für die und ich kann nicht herausfinden, warum. Es scheint nicht viel Dokumentation darüber zu geben.BNFC Bad Coercion in Regel

Hier sind die Fehler, die ich bin immer:

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 ::= 

Hier eine Probe der BNFC Datei ist:

_.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 ::=; 

Es scheint zu sein, dass ich das _. Etikett falsch verwenden. Aber das Handbuch hat nur eine oder zwei Zeilen, die beschreiben, wie es benutzt wird. Was mache ich hier falsch?

+2

Kann nicht mit der Dokumentation helfen. Ich schlage vor, Sie versuchen, eine Grammatik mit 1-2 Regeln zu erhalten, um "bnfc" zu übergeben, bevor Sie etwas Großes ausprobieren und Ihr Ergebnis mit den Grammatikbeispielen vergleichen, die Sie finden können. (Meinung: Wenn Sie ein schlecht dokumentiertes Werkzeug haben, würde ich ein anderes Werkzeug wählen. Sie wählten einen Parser-Generator aus Bequemlichkeit und um Ihnen Zeit zu sparen, richtig?). –

Antwort

1

Vom documentation:

Unterstreichungen sind natürlich nur sinnvoll als Ersatz von einargumentigen Konstrukteuren, wo der Wert Typ gleich dem Argument-Typ ist.

Was bedeutet, dass Sie nur _ verwenden können, wenn Sie genau eine Nicht-Terminal in der rechten Seite der Regel haben und dass nicht-Terminal ist das gleiche wie die auf der linken Seite. So können Sie etwas tun wie _. A ::= "(" A ")" ; aber nicht _. A ::= "(" B ")" ; noch _. A ::= "(" A A ")" ;.

In Ihrem Beispiel schlage ich vor, dass Sie jeder Regel eine Bezeichnung geben, _ wird meistens verwendet, um die AST in einigen Fällen zu vereinfachen.

BTW gibt es auch eine Syntaxverknüpfung für lists of things.