пытался использовать этот простой грамматик, который не имеет ошибки.
но разбирает несколько раз.
мне пришлось добавить backtracking = true, чтобы он работал без ошибок.
вот грамматика:
grammar grammer;
options {
backtrack=true;
memoize=true;
}
program :
'class' 'Program' '{' (field_decl)* (method_decl)* '}' EOF {System.out.print(":)"); }
| syntax_error {System.out.print(":(");}
;
field_decl :
type (Id | (Id '[' Int_literal ']')) (',' (Id | (Id '[' Int_literal ']')))* ';'
| syntax_error
;
method_decl :
(type | 'void') Id '(' (type Id) declcomma* ')' block
| (type | 'void') Id '(' ')' block ;
declcomma
:
(',' type Id )
;
block : '{' (var_decl)* (statement)* '}'
;
var_decl :
type Id (',' Id )* ';' ;
statement : location assign_op expr ';'
| method_call ';'
| 'if' '('expr')' block
| 'if' '('expr')' block 'else' block
| 'for' Id '=' expr ',' expr block
| 'return' (expr)? ';'
| 'break' ';'
| 'continue' ';'
| block
| 'while' '(' expr ')' block
| syntax_error
;
assign_op: '='
| '+='
| '-=' ;
method_call :
method_name '(' expr (commaexp)* ')'
| 'callout' '(' String_literal (',' callout_arg)* ')' ;
commaexp
:
',' expr
;
method_name : Id;
location : Id
| Id '[' expr ']';
expr : (location | method_call | literal | ('-'expr) | ('!'expr) | ('(' expr ')')) (bin_op expr)*
;
callout_arg : expr|String_literal;
bin_op : arith_op|rel_op|eq_op|cond_op;
literal : Int_literal|Char_literal|Bool_literal;
type : 'int'|'boolean';
Id : ALPHA (Alpha_num)*;
arith_op : '-'|'+'|'*'|'/'|'%';
rel_op : '<'|'>'|'<='|'>=';
eq_op : '=='|'!=';
cond_op : '&&'| '||' ;
syntax_error
:
'class' 'Program' field_decl* method_decl* {System.out.println("synta Error: you missed placing '{}' for your main block");}
| 'class' 'Program' '{' field_decl* method_decl* {System.out.println("synta Error: you missed placing '{}' for your main block");}
| 'class' 'Program' field_decl* method_decl* '}' {System.out.println("synta Error: you missed placing '{}' for your main block");}
| type (Id | (Id '[' Int_literal ']')) ( ',' (Id | (Id '[' Int_literal ']')))* {System.out.println("syntax error: you missed :';'"); }
| location assign_op expr {System.out.println("syntax error: you missed :';'"); }
| method_call {System.out.println("syntax error: you missed :';'"); }
| 'for' Id '=' expr ',' expr block{System.out.println("syntax error: you missed :';'"); }
| 'return' (expr)? {System.out.println("syntax error: you missed :';'"); }
| 'break' {System.out.println("syntax error: you missed :';'"); }
| 'continue' {System.out.println("syntax error: you missed :';'"); }
;
String_literal
: '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
;
Char_literal: '\'' ( ESC_SEQ | ~('\''|'\\') ) '\''
;
Int_literal : Decimal_literal|Hex_literal;
fragment
Alpha_num : ALPHA|DIGIT;
fragment
ALPHA : ('a'..'z')|('A'..'Z')|'_';
fragment
DIGIT : ('0'..'9');
fragment
HEX_DIGIT : ('0'..'9')|('a'..'f')|('A'..'F');
fragment
Decimal_literal : DIGIT DIGIT*;
fragment
Hex_literal : '0x' HEX_DIGIT+;
fragment
Bool_literal : 'true'|'false';
Ws : (' '|'\r'|'\n'|'\t')* {skip();};
COMMENT
: '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
;
fragment
ESC_SEQ
: '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
| UNICODE_ESC
| OCTAL_ESC
;
fragment
OCTAL_ESC
: '\\' ('0'..'3') ('0'..'7') ('0'..'7')
| '\\' ('0'..'7') ('0'..'7')
| '\\' ('0'..'7')
;
fragment
UNICODE_ESC
: '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
;
Все, что я хотел, это сделать правильное дерево разбора.
например, теперь у этого есть два терминала для «класса».
и квадраты в отладчике, зеленые и черные.
также пытался удалить эти параметры, но это вызывает некоторые ошибки.