2016-11-08 20 views
0

私は自分の文法を書いた:ANTLR4の文法規則で内部エラー

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 ; 

私はこのエラーを得た:

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

このエラーはなぜ起こったか私にはわかりません。 int_literalが定義されました。なぜこのエラーが起きたのか説明してください。私は理由を見つけられませんでした。

ありがとうございます。

答えて

0

私はあなたのコードを調べましたが、主な問題は、あなたがレクサールールからパーサールールを分離していないことです。これは、大文字/小文字の区別を使用して行われます。レクサールールは大文字で定義されています。これが修正されると、ルール "char"が定義されていないという点で、文法にも1つの誤りがありました。ルールが組み合わさ文法に重要であるであるので、区別セマンティクスため

/* 
* 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 ; 

レクサールールは、トークンのストリームを作成するために使用され、パーサー:ここで

は修正バージョンです。

thisフォーラムには良い記事がありますが、その違いの正確な内訳と必要な理由がかなり分かります。しかし、ルールの欠如とレクサーの定義の欠如以外は、それはすべて良かった。 INT:DIGIT +を覚えておいてください。 //レクサールールは大文字で表記されます。

あなたのプロジェクトに幸運を祈る!

+0

レクサールールでは最初の文字のみが大文字でなければなりません。 'Digit'は有効なレクサールール名です。 –

+0

真実ですが、多くの文法を共有しても有効ですが、伝統的に完全にブロック化されているので、分かりやすいように見えますが、有効な点は – D3181

+0

ありがとうございます。私はレクサーのルールとパーサーのルールを忘れていました。私の全然悪い。 – caoduylam

関連する問題