2017-12-01 19 views
0

저는 ANTLR에 새로운 새소식입니다. ANTLR을 사용하여 2 개의 JAVA 파일을 컴파일 할 때도 동일한 오류가 발생했습니다. 나무는 결점없이 잘 보입니다. 이 오류의 근본 원인에 대한 단서를 찾을 수 없습니다. 사용 된 ANTLR 버전은 'ANTLR 4'입니다. 아무도 그것을 고칠 방법을 알고 있습니까? 미리 감사드립니다!ANTLR 오류 : '<EOF>'입력시 실행 가능한 대안이 없습니다. 그것을 고치는 방법?

1) ANTLR 파일 test.g4는

grammar test; 

// Syntax Specification ==> Context-free Grammar 
pa1: 
    mainClass aClass*; 

mainClass: 
    classDeclaration '{' mainDeclaration ('{'body'}'|'{''{'body'}''}') '}'; 

mainDeclaration: 
    'public' 'static' 'void' 'main' '(' 'String''['']' ID ')'; 

aClass: 
    classDeclaration '{' body '}'; 

classDeclaration: 
    'class' ID; 

aMethod: 
    methodDeclaration'{'body'}'; 

methodDeclaration: 
    type ID'('parameterList')'; 

body: 
    (varDeclaration|statement|expression|aMethod)*; 

varDeclaration: 
    type ID ';' ; 

statement: 
    (ID|arrayElement) '=' (NUM|ID|string|aChar|('new' type)? arrayElement|'new' (type|ID) '('')'|aCall|mathExpression)';'; //(ID|arrayElement) '=' (NUM|ID|string|aChar|arrayElement|aCall|mathExpression|booleanExpression)';'; 

string: 
    '"' .*? '"'; 

aChar: 
    '\''(.?|'+'|'-')'\''; 

expression: 
    ID';'|whileExpression|ifExpression|sysPrintExpression|returnExpression; 

ifExpression: 
    'if''('booleanExpression')' ((varDeclaration|statement|expression)*|'{'(varDeclaration|statement|expression)*'}') 
    ('else''if''('booleanExpression')' ((varDeclaration|statement|expression)*|'{'(varDeclaration|statement|expression)*'}'))? 
    ('else'((varDeclaration|statement|expression)*|'{'(varDeclaration|statement|expression)*'}'))?; 

whileExpression: 
    'while''('booleanExpression')' '{'(varDeclaration|statement|expression)*'}'; 

sysPrintExpression: 
    'System''.''out''.''println''('(NUM|arrayElement|aCall)')'';'; 

returnExpression: 
    'return'(NUM|ID)';'; 

compExpression: 
    (ID|NUM|mathExpression) COMPOPERATOR (ID|NUM|'('mathExpression')'|'('ID')'); 

mathExpression: 
    (ID|NUM) (PLUS|MINUS|MULT|DIV)(ID|NUM|('('ID'.'ID'('parameterList')'')')); 

singleBooleanExpression: 
    '!'?('('compExpression')'|compExpression|aCall|ID);//(LOGICALOPERATOR('!'?(compExpression|aCall|ID|string|aChar)))?;  

doubleBooleanExpression: 
    '(''!'?('('compExpression')'|compExpression|aCall|ID)')'LOGICALOPERATOR('(''!'?(compExpression|aCall|ID|string|aChar)')'); 

booleanExpression: 
    singleBooleanExpression|doubleBooleanExpression;  

aCall: 
    (ID|'new'? ID '('')')calling|'('(ID|ID'('')')calling')'calling; 

calling: 
    '.'(ID('('parameterList')')?); 

parameterList: 
    (NUM|type? ID|aChar|string|mathExpression|aCall)?(','(NUM|type? ID|aChar|mathExpression))*; 

arrayElement: 
    ID?'['(ID|NUM)']'; 

type: 
    'int''['']'|'boolean'|'int'|'char'|ID; 

// Lexer Specification ==> Regular Expressions 
NUM: ('0' | [1-9][0-9]*); 
ID: [a-zA-Z_][0-9a-zA-Z_]*; 
PLUS : '+' ; 
MINUS : '-' ; 
MULT : '*' ; 
DIV : '/'; 
COMPOPERATOR: '<'|'>'; 
LOGICALOPERATOR: '=='|'||'|'&&'; 
WHITESPACE: [ \t\r\n]+ -> skip; 
COMMENT: ('/*'.*?'*/'|'//'~[\r\n|\r|\n]*) -> skip; 

2) JAVA의 FILE1 아래와 같이 MyChar.java이며 아래와 같다

class MyChar{ 
    public static void main(String[] a){ 
     { 
      System.out.println(new CharEditor().whichIsSmaller('a', 'c')); 
      System.out.println(new CharEditor().whichIsSmaller('a', 'A')); 
      System.out.println(new CharEditor().whichIsSmaller('1', 'd')); 
      System.out.println(new CharEditor().whichIsSmaller('-', '+')); 
      // System.out.println("There are total " + new MyChar().countFromCharToChar('a', 'z', true) + " characters in between a and z"); 
      System.out.println(new CharEditor().countChars("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", 'c')); 
     } 
    } 
} 

class CharEditor { 

    char whichIsSmaller(char firstChar, char secondChar){ 
     char returnChar; 

     if(secondChar < firstChar) //the comparison is based on the character's ASCII code 
     returnChar = firstChar; 
     else 
     returnChar = secondChar; 
     return returnChar; 
    } 

    int countChars(String str, char c){ 
     int n; 
     int sz; 
     char c1; 
     int counter; 

     counter = 0; 

     sz = str.length(); 
     n = 0; 
     while (n < sz) { 
      c1 = str.charAt(n); 
      if (c1 == c) { 
       counter = counter + 1; 
      } 
      n = n + 1; 
     } 
     return counter; 
    } 
} 

3) 자바 파일 2 아래 MyString.java 인 ,

class MyString{ 
    public static void main(String[] a){ 
     { 
      System.out.println(new StringEditor().removeSpace("Hello World And Happy Coding")); 
      System.out.println(new StringEditor().containsChar("Hello World And Happy Coding", 'd')); 
      System.out.println(new StringEditor().containsChar("Hello World And Happy Coding", 'b')); 
     } 
    } 
} 

class StringEditor { 
    String removeSpace(String str) { 
     String toReturn; 
     int n; 
     int sz; 
     char c; 

     toReturn = ""; 
     sz = str.length(); 
     n = 0; 
     while (n < sz) { 
      c = str.charAt(n); 
      if (c == ' ') { 

      } else { 
       toReturn = toReturn + c; 
      } 
      n = n+1; 
     } 

     return toReturn; 
    } 

    boolean containsChar(String str, char c) { 
     int n; 
     int sz; 
     char c1; 

     boolean toReturn; 

     toReturn = false; 

     sz = str.length(); 
     n = 0; 
     while (n < sz) { 
      c1 = str.charAt(n); 
      if (c1 == c) { 
       toReturn = true; 
       break; 
      } 
      n = n+1; 
     } 

     return toReturn; 
    } 
} 
+0

에 관한 파일 1, 문법>

다운로드 - 자바 갈 준비가있다는 from the Antlr site 은 문법 'string'이'type' 규칙에서 빠져 있기 때문에 26 행 int countChars (String str, char c) {'을 파싱 할 수 없습니다. 또한'=='을'LOGICAL OPERATOR'에서'COMPOPERATOR'로 이동하십시오. – BernardK

+0

감사합니다. Bernard! 그것은 파일 1에 대해 작동합니다. 그리고 당신에 의해 계몽 된, 나는 파일 2에 대해서도 그것을 해결했습니다. –

답변

0

사실 파일 2에 대한 문제가 해결되었지만 그럼에도 불구하고 나는 대답을 게시하고 있습니다. 엔.

문제가 발생하면 가장 먼저 할 일은 렉서가 입력을 어떻게 해석했는지 확인하기 위해 토큰을 표시하는 것입니다. 종종 우리가 믿는 것이 아닙니다. 파일 2 :

$ grun Question question -tokens -diagnostics input2.text 
... 
[@131,652:653='if',<'if'>,23:12] 
[@132,655:655='(',<'('>,23:15] 
[@133,657:657='c',<ID>,23:17] 
[@134,659:660='==',<COMP_OPERATOR>,23:19] 
[@135,662:662=''',<'''>,23:22] 
[@136,664:664=''',<'''>,23:24] 
[@137,665:665=')',<')'>,23:25] 
[@138,667:667='{',<'{'>,23:27] 
[@139,682:682='}',<'}'>,25:12] 

는 아포스트로피 암시 때문에 문 (23)

if (c == ' ') { 

에 단일 공백 ​​문자가없는 규칙

aChar: 
    '\'' (.? | '+' | '-') '\''; 

에 의해, 두 개의 분리 된 '으로 해석되는 것을 보여줍니다 이 파서 규칙 aChar의 토큰으로 정의 된 공간은

에 의해 버려집니다.
WHITESPACE: [ \t\r\n]+ -> skip; 

렉서 규칙에 따라 렉서는 전체적으로 ' '을 고려해야합니다. 즉,

A_CHAR : '\'' ('+' | '-' | .?) '\'' ; 

지금 토큰이 올바른지 내가 렉서 규칙에 구문 분석기 규칙 aChar을 변경 한 이유는 다음과 같습니다

[@127,652:653='if',<'if'>,23:12] 
[@128,655:655='(',<'('>,23:15] 
[@129,657:657='c',<ID>,23:17] 
[@130,659:660='==',<COMP_OPERATOR>,23:19] 
[@131,662:664='' '',<A_CHAR>,23:22] 
[@132,665:665=')',<')'>,23:25] 

는 또한 string 파서 규칙, "Lorem ipsum dolor sit met ..."의 각 단어는 ID로 해석됩니다 있습니다, 렉서 규칙 STRING을 사용하면 전체 문장이 단일 토큰으로 캡처됩니다.

또 다른 개선 사항은 DRY 원리 (직접 반복하지 마십시오)를 적용하는 것입니다. 예를 들어 ifExpression의 경우 (varDeclaration|statement|expression)이라는 표현을 6 번 반복합니다. 이것은 서브 룰을 사용하여 줄일 수 있습니다.

grammar Question; 

question 
@init {System.out.println("Question last update 1803");} 

// Syntax Specification ==> Context-free Grammar 
    : mainClass aClass*; 

mainClass 
    : classDeclaration '{' mainDeclaration declaration_block '}'; 

mainDeclaration: 
    'public' 'static' 'void' 'main' '(' 'String' '[' ']' ID ')'; 

aClass: 
    classDeclaration declaration_block ; 

classDeclaration: 
    'class' ID; 

aMethod: 
    methodDeclaration declaration_block ; 

methodDeclaration: 
    type ID parameterList ; 

declaration_block 
    : '{' declarattion_body* '}' 
    | '{' declaration_block '}' 
    ; 

declarattion_body 
    : statement 
    | aMethod 
    ; 

statement_block 
    : '{' statement* '}' 
    ; 

statement 
    : varDeclaration 
    | assignment 
    | statement_expression 
    ; 

varDeclaration: 
    type ID ';' ; 

assignment: 
    (ID|arrayElement) '=' (NUM|ID|STRING|A_CHAR|('new' type)? arrayElement|'new' (type|ID) '('')'|aCall|mathExpression)';'; //(ID|arrayElement) '=' (NUM|ID|STRING|A_CHAR|arrayElement|aCall|mathExpression|booleanExpression)';'; 

statement_expression 
    : ID ';' 
    | whileExpression 
    | ifExpression 
    | sysPrintExpression 
    | returnExpression 
    ; 

ifExpression 
    : 'if' '(' booleanExpression ')' statement_if 
     ('else' 'if' '(' booleanExpression ')' statement_if)? 
     ('else' statement_if)? 
    ; 

statement_if 
    : statement* 
    | statement_block 
    ; 

whileExpression 
    : 'while' '(' booleanExpression ')' statement_block 
    ; 

sysPrintExpression: 
    'System''.''out''.''println''('(NUM|arrayElement|aCall)')'';'; 

returnExpression: 
    'return'(NUM|ID)';'; 

compExpression 
    : (ID | NUM | mathExpression) COMP_OPERATOR (ID | NUM | A_CHAR | '(' mathExpression ')' | '(' ID ')') ; 

mathExpression: 
    (ID|NUM) (PLUS|MINUS|MULT|DIV) (ID | NUM | ('(' ID '.' ID parameterList ')')); 

singleBooleanExpression 
    : '!'? ('(' compExpression ')' | compExpression | aCall | ID) ; //(LOGICAL_OPERATOR('!'?(compExpression|aCall|ID|STRING|A_CHAR)))?;  

doubleBooleanExpression: 
    '(''!'?('('compExpression')'|compExpression|aCall|ID)')'LOGICAL_OPERATOR('(''!'?(compExpression|aCall|ID|STRING|A_CHAR)')'); 

booleanExpression 
    : singleBooleanExpression 
    | doubleBooleanExpression 
    ; 

aCall: 
    (ID|'new'? ID '('')')calling|'('(ID|ID'('')')calling')'calling; 

calling: 
    '.' (ID (parameterList)?) ; 

parameterList 
    : '(' 
     (NUM | type? ID | A_CHAR | STRING | mathExpression | aCall)? 
     (',' (NUM | type? ID | A_CHAR | mathExpression))* 
     ')' 
    ; 

arrayElement: 
    ID? '[' (ID | NUM) ']' ; 

type 
    : 'int' '[' ']' 
    | 'boolean' 
    | 'int' 
    | 'char' 
    | 'String' // <----- added 
    | ID; 

// Lexer Specification ==> Regular Expressions 
NUM : '0' | [1-9][0-9]* ; 
ID : [a-zA-Z_][0-9a-zA-Z_]* ; 
PLUS : '+' ; 
MINUS : '-' ; 
MULT : '*' ; 
DIV : '/' ; 
COMP_OPERATOR : '<' | '>' | '==' ; // <----- changed 
LOGICAL_OPERATOR : '||' | '&&' ; // <----- changed 
STRING : '"' .*? '"' ; 
A_CHAR : '\'' ('+' | '-' | .?) '\'' ; 
WHITESPACE: [ \t\r\n]+ -> skip; 
//COMMENT: ('/*'.*?'*/'|'//'~[\r\n|\r|\n]*) -> skip; 
/* 
warning(180): Question.g4:103:27: chars "" used multiple times in set [\r\n|\r|\n] 
warning(180): Question.g4:103:27: chars "|" used multiple times in set [\r\n|\r|\n] 
warning(180): Question.g4:103:27: chars " 
" used multiple times in set [\r\n|\r|\n] 
*/ 
COMMENT  : '/*' .*? '*/' -> skip ; 
LINE_COMMENT : '//' ~[\r\n]* -> skip; 

그러나 그것은 단지 두 개의 게시 된 파일에서 작동 :

따라서 문법이 될 수 있습니다.이와 함께 : 기존의 언어에 대한 문법을 ​​작성

$ grun Question question input3.text 
Question last update 1803 
line 8:0 extraneous input 'public' expecting {<EOF>, 'class'} 
line 9:1 no viable alternative at input '{public' 
line 9:39 mismatched input 'extends' expecting '{' 

흥미로운하지만 어려운 :

class MyString{ 
    public static void main(String[] a){ 
     { 
     } 
    } 
} 

public class test { 
    public static class UnderlineListener extends BaseErrorListener { 
    } 
} 

작동하지 않습니다. > 소스 저장소

github

에서 모두의 최대 - -> 추가 문법

This repository