简体   繁体   中英

ANTLR mismatched input expecting ID

I am still working on the same Haskell based grammar in case you saw my previous post. Most of the errors are gone now but I have another problem.

My grammar is as follows I know this is a very large and tedious thing to read but I need this for my final so I'm sorry and I appreciate any help at all: (a lot of the logic is missing but these are all the rules required)

grammar T;



options {
language=Java;
backtrack=true;
}

tokens{
NUM = 'num';
LIST = 'list'; 
EVEN = 'even';
ODD = 'odd'; 
TWICE = 'twice';
HEAD = 'head';
TAIL = 'tail';
LENGTH = 'length'; 
MAX = 'max'; 
REV = 'reverse';
INC = 'incAll'; 
SORT = 'sort'; 
KEEP = 'keep';
DROP = 'drop';
POLY = 'poly'; 
}


@header {
import java.util.Hashtable;
import java.util.ArrayList;
}

@members
{
Hashtable <String, Integer> intMemory= new Hashtable<String, Integer>();
Hashtable <String, ArrayList> listMemory= new Hashtable <String, ArrayList>();
}


prog:   stat+ 
;

stat:   numDecl ';' //declares a variable containing an int
|listDecl ';' //declares a variable containing a list 
|numAdd ';' //adds two integers directly or through getting from the int hashtable  
|numEven ';' //determines whether or not int or id value is even
|numOdd ';' //determines whether or not int or id value is odd
|numTwice ';' {System.out.println($numTwice.value);} //double values and prints
|listHead ';'  {System.out.println($listHead.value);} //returns list head
|listTail ';' //returns list tail 
|listLength ';' //{System.out.println($listLength.value);} // returns list length
|listConc ';' //{System.out.println($listConc.value);} //concatenates 2 lists
|listMax ';' //{System.out.println($listMax.value);} //returns max of a list
|listReverse  ';' //{System.out.println($listReverse.value);}//reverses a list
|listInc  ';'  //{System.out.println($listInc.value);} //increments each list value by 1
|listSort  ';' //{System.out.println($listSort.value);}//sorts a list 
|listConst  ';'  //{System.out.println($listConst.value);}//constructs a list from another one 
|bothKeep  ';'  //{System.out.println($bothKeep.value);}// keeps a specified number of elements from a list
|bothDrop  ';'  //{System.out.println($bothDrop.value);}// drops a specified number of elements from the list
|bothPoly ';' //{System.out.println($bothPoly.value);}//evaluates a polynomial at a certain value

;

numDecl:
NUM  ID '=' atom {intMemory.put($ID.text, new Integer($atom.value));}
;

listDecl
@init {
int count = 0;
ArrayList<Integer> list = new ArrayList<Integer>();
}:
LIST ID '=' '[' a1=atom {list.add($a1.value);} (',' a2=atom {list.add($a2.value);} )* ']' {listMemory.put($ID.text, list);}
;

numAdd returns [int value]: 
e=numMult {$value=$e.value;} ('+' e1=numMult {$value+=$e1.value;} | '-' e1=numMult {$value-=$e1.value;})* {System.out.println($numAdd.value);}
; 

numMult returns [int value]: 
e=atom {$value=$e.value;} ('*' e1=atom {$value*=$e1.value;} | '/' e1=atom {if($e1.value !=0) $value/=$e1.value;
                                     else System.out.println ("Division by 0 is impossible");})*
;

numEven:
EVEN (WS)+ atom {if ($atom.value\%2==0) System.out.println("Is Even.");}
;

numOdd:
ODD (WS)+ atom {if ($atom.value\%2==1) System.out.println("Is Odd.");}
;

numTwice returns [int value]:
TWICE (WS)+ atom {$value= 2*($atom.value); System.out.println($value);}
;

listHead returns [int value]:
HEAD headTail
;

headTail returns [int value]: 
ID {$value= (Integer) listMemory.get($ID.text).get(0);}
|'[' x=atom (',' atom )*']' {$value=$x.value;} 
;

listTail: 
TAIL tailTail
;

tailTail 
@init {
int count = 0;
ArrayList<Integer> list = new ArrayList<Integer>();
}:
ID {System.out.println("[ "); for (int i=1; i<listMemory.size();i++) System.out.println(listMemory.get($ID.text).get(i)+","); System.out.println(" ]");}

|'[' a1=atom {list.add($a1.value);} (',' a2=atom{list.add($a2.value);} )* ']' {System.out.println("[ "); for (int i=1; i<list.size();i++) System.out.println(list.get (i)+","); System.out.println(" ]");}
;

listLength:
LENGTH lengthTail
; 

lengthTail returns [int value]
@init {
int count = 0;
ArrayList<Integer> list = new ArrayList<Integer>();
}:

ID {$value=listMemory.get($ID.text).size();}

| '[' a1=atom {list.add($a1.value);} (',' a2=atom{list.add($a2.value);} )* ']' {$value=list.size();}
;

listConc: 
ID '+' '+' concTail
|'[' atom(',' atom)*']' '+' '+' concTail
;

concTail returns [ArrayList list]: 
ID {$list=listMemory.get($ID.text);}
| '[' atom(',' atom)*']'
; 


listMax:
MAX maxTail
;

maxTail: ID
| '[' atom (',' atom )*']'
;

listReverse: 
REV revTail
;
revTail: 
 ID
| '[' atom (',' atom )*']'
;

listInc: 
INC incTail
;

incTail: 
ID
| '[' atom (',' atom )*']'
;

listSort:
SORT sortTail
;

sortTail:
ID
|'[' atom (',' atom )*']'
;

listConst:
'[' atom constTail '|' ID '<-' ID ']'
;
constTail: 
'+' atom
|'-' atom
|'*' atom
|'/' atom
;

bothKeep: 
KEEP atom keepTail
;

keepTail
@init {
int count = 0;
ArrayList<Integer> list = new ArrayList<Integer>();
}:
'[' a1=atom {list.add($a1.value);} (',' a2=atom{list.add($a2.value);} )* ']' 
|ID
;

bothDrop: 
DROP atom dropTail
;

dropTail returns [ArrayList value] 
@init {
int count = 0;
ArrayList<Integer> list = new ArrayList<Integer>();
}:
'[' a1=atom {list.add($a1.value);} (',' a2=atom{list.add($a2.value);} )* ']' 
|ID
;

bothPoly: 
POLY atom polyTail
;

polyTail returns [ArrayList value] 
@init {
int count = 0;
ArrayList<Integer> list = new ArrayList<Integer>();
}:
'['  a1=atom {list.add($a1.value);} (',' a2=atom{list.add($a2.value);} )* ']' {$value=list;}
|ID
;

atom returns [int value]:
 INT {$value = Integer.parseInt ($INT.text);}
| ID 
    {
        Integer v= (Integer)intMemory.get($ID.text);
        if (v!=null) {$value=v.intValue();}
        else { 
            System.err.println("Undefined variable "+$ID.text);
            }
    }
| '(' numAdd ')' {$value=$numAdd.value;}
;



Letter: 'a'..'z';
Digit: '0'..'9';

ID  :  'a'..'z'('0'..'9')*;
INT : '0'..'9'+ ;
WS :   (' '|'\t'|'\n'|'\r')+ {skip();} ;

I have given it the following input nothing on lists yet because I haven't implemented it their methods yet:

num x=4;
num y=9;
x+2;
2+3;
2-3;
x-2;
2*3;
x*2;
2/4;  
x/3;
x/0;
even x;
odd 5;
odd y;
twice x; 
twice y; 
twice 2; 

When I run it through the command prompt I get the following:

C:\Users\Kamal\Desktop\Antlr>java -cp .;antlr-3.2.jar org.antlr.Tool T.g

C:\Users\Kamal\Desktop\Antlr>javac -cp .;antlr-3.2.jar *.java

C:\Users\Kamal\Desktop\Antlr>java -cp .;antlr-3.2.jar TestT
line 1:4 mismatched input 'x' expecting ID
line 2:4 mismatched input 'y' expecting ID

I would appreciate any help at all. Even if no one can really answer. Thanks a lot!

The problem is probably the same as in this case .

While your ID rule matches the input given, there might be another rule that matches your 'x' and 'y' values. Unfortunately, I haven't got antlr set up here to test it, but your Letter rule might cause the problem. You should try declaring your Digit and Letter rules as fragment

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM