2016-11-08 8 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

Я просмотрел ваш код, и главная проблема заключается в том, что вы не разделяли правила Parser из правил Lexer. Это делается с использованием чувствительности Capitals/Case. Правила Lexer определяются в шапках. как только это было исправлено, ваша грамматика также имела еще одну ошибку в том, что правило «char» не определено.

здесь измененная версия:

/* 
* 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 с довольно подробной разбивкой на разницу и почему ее необходимо. Но кроме недостающего правила и отсутствия определения lexer все было хорошо. Просто помните INT: DIGIT +; // Правила lexer в шапках.

Удачи вам в вашем проекте!

+0

Только первая буква должна быть в верхнем регистре для правила лексера, например. 'Digit' является допустимым именем правила lexer. –

+0

Правда, но в действительности многие общие грамматики кажутся традиционно полностью блокируемыми, чтобы облегчить их различие, но действительный пункт :) – D3181

+0

Большое спасибо. Я забыл о правилах lexer и правилах парсера. Мой плохой. – caoduylam

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

  • Нет связанных вопросов^_^