2016-11-08 50 views
0

我寫我自己的語法:內部錯誤規則

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

我經歷了您的代碼,主要問題是您沒有從Lexer規則中分離出Parser規則。這是使用首都/區分大小寫完成的。 Lexer規則在大寫字母中定義。一旦這個問題得到糾正,你的語法還有1個錯誤,因爲規則「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論壇,正是差異的相當詳細的分類,爲什麼它的需要。但除了缺少規則和缺乏詞法分析的定義,這一切都很好。請記住INT:DIGIT +; //詞法分析規則

祝您的項目順利!

+0

只有第一個字母必須是一個詞法規則上的情況下,例如'Digit'是一個有效的詞法分析規則名稱。 –

+0

真實的,但同時有效很多共同的語法似乎通常是完全塊,使其更容易區分它們,但有效的點:) – D3181

+0

非常感謝。我忘記了詞法分析器規則和解析器規則。我一點都不好。 – caoduylam