1

如果您看到我以前的帖子,我仍在研究相同的基于 Haskell 的语法。大多数错误现在都消失了,但我还有另一个问题。

我的语法如下我知道这是一个非常大而且很乏味的东西,但是我的期末考试需要这个,所以我很抱歉,我很感激任何帮助:(很多逻辑都丢失了,但这些都是需要规则)

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();} ;

我在列表中没有给它以下输入,因为我还没有实现它们的方法:

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; 

当我通过命令提示符运行它时,我得到以下信息:

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

我将不胜感激。即使没有人能真正回答。非常感谢!

4

1 回答 1

1

问题可能与本例相同。

虽然您的ID规则与给定的输入匹配,但可能还有另一个规则与您的'x''y'值匹配。不幸的是,我没有在这里设置 antlr 来测试它,但你的Letter规则可能会导致问题。您应该尝试将您的DigitLetter规则声明为fragment

于 2013-07-23T07:42:08.237 回答