2016-11-08 3 views
0

ich meine eigene Grammatik schrieb:interner Fehler in ANTLR4 Grammatikregeln

grammar SimpleCode; 

program: 'class Program' '{' field_decl* method_decl* '}' ; 

field_decl: type id_int_list ; 

id_int: id 
     | id '[' int_literal ']' 
     ; 

id_int_list: id_int 
      | id_int (',' id_int)* 
      ; 

method_decl: (type | 'void') id id_type_list? block ; 

id_type_list: (type id) 
      | (type id) (','(type id))* 
      ; 

block: '{' var_decl* statement* '}' ; 

var_decl: type id_list ; 

id_list: id 
     | id (',' id)* 
     ; 

type: 'int' 
    | 'boolean' 
    ; 

statement: location assign_op expr ';' 
     | method_call ';' 
     | 'if' expr block 'else' block 
     | 'for' id '=' expr ',' expr block 
     | 'return' expr? ';' 
     | 'break' ';' 
     | 'continue' ';' 
     | block 
     ; 

assign_op: '=' 
     | '+=' 
     | '-=' 
     ; 

method_call: method_name expr_list? 
      | 'callout' (string_literal (',' callout_arg_list)?) 
      ; 

expr_list: expr 
     | expr (',' expr)* 
     ; 

callout_arg_list: callout_arg 
       | callout_arg (',' callout_arg)* 
       ; 

method_name: id ; 

location: id 
     | id '[' expr ']' 
     ; 

expr: location 
    | method_call 
    | literal 
    | expr bin_op expr 
    | '-' expr 
    | '!' expr 
    | '(' expr ')' 
    ; 

callout_arg: expr 
      | string_literal 
      ; 

bin_op: arith_op 
     | rel_op 
     | eq_op 
     | cond_op 
     ; 

arith_op: '+' 
     | '-' 
     | '*' 
     | '\\' 
     | '%' 
     ; 

rel_op: '>' 
     | '<' 
     | '>=' 
     | '<=' 
     ; 

eq_op: '==' 
    | '!=' 
    ; 

cond_op: '&&' 
     | '||' 
     ; 

literal: int_literal 
     | char_literal 
     | bool_literal 
     ; 

id: alpha alpha_num* ; 

alpha_num: alpha 
     | digit 
     ; 

alpha: ('a'..'z' | 'A'..'Z') ; 

digit: '0'..'9' ; 

hex_digit: digit 
     | 'a'..'f' 
     | 'A'..'F' 
     ; 

int_literal: decimal_literal 
      | hex_literal 
      ; 

decimal_literal: digit digit* ; 

hex_literal: '0x' hex_digit hex_digit* ; 

bool_literal: 'true' 
      | 'false' 
      ; 

char_literal: '\'' char '\'' ; 


string_literal: '\"' char* '\"' ; 

WS: [ \t\r\n]+ ->skip ; 

habe ich diesen Fehler:

error(20): SimpleCode.g4:8:12: internal error: Rule int_literal undefined 

Ich weiß nicht, warum dieser Fehler passiert ist. Das int_literal wurde definiert. Bitte erklären Sie mir, warum dieser Fehler passiert ist. Ich habe den Grund nicht herausgefunden.

Danke für Ihre Hilfe.

Antwort

0

Ich ging Ihren Code durch und das Hauptproblem ist, dass Sie die Parser-Regeln nicht von den Lexer-Regeln getrennt haben. Dies geschieht mithilfe der Groß-/Kleinschreibung. Lexer-Regeln sind in Großbuchstaben definiert. Sobald dies korrigiert wurde, hatte Ihre Grammatik auch einen weiteren Fehler, da die Regel "char" nicht definiert war.

hier ist eine geänderte Fassung:

/* 
* To change this license header, choose License Headers in Project Properties. 
* To change this template file, choose Tools | Templates 
* and open the template in the editor. 
*/ 

grammar SimpleCode; 


program: 'class Program' '{' field_decl* method_decl* '}' ; 

field_decl: type id_int_list ; 

id_int: id 
     | id '[' int_literal ']' 
     ; 

id_int_list: id_int 
      | id_int (',' id_int)* 
      ; 

method_decl: (type | 'void') id id_type_list? block ; 

id_type_list: (type id) 
      | (type id) (','(type id))* 
      ; 

block: '{' var_decl* statement* '}' ; 

var_decl: type id_list ; 

id_list: id 
     | id (',' id)* 
     ; 

type: 'int' 
    | 'boolean' 
    ; 

statement: location assign_op expr ';' 
     | method_call ';' 
     | 'if' expr block 'else' block 
     | 'for' id '=' expr ',' expr block 
     | 'return' expr? ';' 
     | 'break' ';' 
     | 'continue' ';' 
     | block 
     ; 

assign_op: '=' 
     | '+=' 
     | '-=' 
     ; 

method_call: method_name expr_list? 
      | 'callout' (string_literal (',' callout_arg_list)?) 
      ; 

expr_list: expr 
     | expr (',' expr)* 
     ; 

callout_arg_list: callout_arg 
       | callout_arg (',' callout_arg)* 
       ; 

method_name: id ; 

location: id 
     | id '[' expr ']' 
     ; 

expr: location 
    | method_call 
    | literal 
    | expr bin_op expr 
    | '-' expr 
    | '!' expr 
    | '(' expr ')' 
    ; 

callout_arg: expr 
      | string_literal 
      ; 

bin_op: arith_op 
     | rel_op 
     | eq_op 
     | cond_op 
     ; 

arith_op: '+' 
     | '-' 
     | '*' 
     | '\\' 
     | '%' 
     ; 

rel_op: '>' 
     | '<' 
     | '>=' 
     | '<=' 
     ; 

eq_op: '==' 
    | '!=' 
    ; 

cond_op: '&&' 
     | '||' 
     ; 

literal: int_literal 
     | char_literal 
     | bool_literal 
     ; 

id: ALPHA alpha_num* ; 

alpha_num: ALPHA 
     | DIGIT 
     ; 

ALPHA: ('a'..'z' | 'A'..'Z') ; 

DIGIT: '0'..'9' ; 

HEX_DIGIT: DIGIT 
     | 'a'..'f' 
     | 'A'..'F' 
     ; 

int_literal: decimal_literal 
      | hex_literal 
      ; 

decimal_literal: DIGIT DIGIT* ; 

hex_literal: '0x' HEX_DIGIT HEX_DIGIT* ; 

bool_literal: 'true' 
      | 'false' 
      ; 

char_literal: '\'' ALPHA '\'' ; 


string_literal: '\"' ALPHA* '\"' ; 

WS: [ \t\r\n]+ ->skip ; 

Die Lexer Regeln zu erstellen, werden verwendet, um Token-Streams und der Parser für die Semantik so Unterscheidung, die Regeln sind, die in einer kombinierten Grammatik wichtig ist.

Es gibt einen guten Beitrag auf this Forum mit einer ziemlich detaillierten Aufschlüsselung genau den Unterschied und warum es benötigt wird. Aber abgesehen von der fehlenden Regel und dem Mangel an Lexer-Definition war alles gut. Erinnere dich einfach an INT: DIGIT +; // lexer Regeln in Großbuchstaben.

Viel Glück bei Ihrem Projekt!

+0

Nur der erste Buchstabe muss Großbuchstaben für eine Lexer-Regel sein, z. 'Digit' ist ein gültiger Lexer-Regelname. –

+0

Wahr, aber während gültig eine Menge der geteilten Grammatiken scheinen in der Regel vollständig Blöcke zu sein, um es einfacher zu machen, sie auseinander zu teilen, aber gültiger Punkt :) – D3181

+0

Vielen Dank. Ich habe vergessen, Lexer-Regeln und Parser-Regeln. Mein schlechtes überhaupt. – caoduylam