antlrworks: многократный анализ - PullRequest
0 голосов
/ 29 июня 2019

пытался использовать этот простой грамматик, который не имеет ошибки. но разбирает несколько раз. мне пришлось добавить 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
;

Все, что я хотел, это сделать правильное дерево разбора. например, теперь у этого есть два терминала для «класса». и квадраты в отладчике, зеленые и черные. также пытался удалить эти параметры, но это вызывает некоторые ошибки.

...