2017-12-01 13 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である)は、Java FILE2は以下の通りである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、文法>

をダウンロード - Javaの行く準備がありますがfrom the Antlr site は文法ルール 'type'に' String'がないので、行26のint countChars(String str、char c){'をパースできません。また、 '=='を 'LOGICALOPERATOR'から' COMPOPERATOR'に移動してください。 – BernardK

+0

ありがとうBernard!それはファイル1のために働いています。あなたによって啓発され、私はファイル2のためにそれを解決しました。 –

答えて

0

ファイル2のための問題を解決したという事実にもかかわらず、私はそれにもかかわらず、私はOを働いていた答えを投稿しますn。

問題が発生した場合、最初に行うことは、トークンを表示してレクサーが入力をどのように解釈したかを確認することです。それはしばしば私たちが信じるものではありません。ファイル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; 

しかし、それには2つのしか投稿ファイルで動作します。これによって:既存の言語のための文法を書く

$ 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

関連する問題