2012-06-17 47 views
1

所以我有一個問題,如果然後其他和whileacc/j定義。有人可以幫忙嗎? input.y在下面。我無法理解yacc錯誤。所以很明顯,12條規則從來沒有減少,但我應該做什麼?Bjacc/j if and while definition

%{ 
import java.lang.Math; 
import java.io.*; 
import java.util.StringTokenizer; 
%} 

/* YACC Declarations */ 
%token NUM 
%left '-' '+' 
%left '*' '/' 
%left NEG /* negation--unary minus */ 
%right '^' /* exponentiation */ 
%token IF ELSE WHILE EXIT 
%token EQ LE GE NE 
%token STRING NUM ID 

%% 

PROGRAM: OPS 
; 

OPS: OP 
|  OPS OP 
; 

OP1: '{' OPS '}' 
|  EXPR ';' 
|  IF '(' EXPR ')' OP1 ELSE OP1 
|  WHILE '(' EXPR ')' OP1 
|  EXIT ';' 
; 

OP2: IF '(' EXPR ')' OP 
|  IF '(' EXPR ')' OP1 ELSE OP2 
|  WHILE '(' EXPR ')' OP2 
; 

OP:  OP1 | OP2 ; 

EXPR: EXPR1 
|  ID '=' EXPR 

EXPR1: EXPR2 
|  EXPR1 EQ EXPR2 
|  EXPR1 LE EXPR2 
|  EXPR1 GE EXPR2 
|  EXPR1 NE EXPR2 
|  EXPR1 '>' EXPR2 
|  EXPR1 '<' EXPR2 
; 

EXPR2: TERM 
|  EXPR2 '+' TERM 
|  EXPR2 '-' TERM 
; 

TERM: VAL 
|  TERM '*' VAL 
|  TERM '/' VAL 
; 

VAL: NUM 
|  '-' VAL 
|  '!' VAL 
|  '(' EXPR ')' 
|  ID 
|  ID '(' ARGS ')' 
; 

ARGS: 
|  ARG 
|  ARGS ',' ARG 
; 

ARG: EXPR 
|  STRING 
; 


input: /* empty string */ 
| input line 
; 

line: '\n' 
| exp '\n' { System.out.println(" " + $1.dval + " "); } 
; 

exp: NUM { $$ = $1; } 
| exp '+' exp { $$ = new ParserVal($1.dval + $3.dval); } 
| exp '-' exp { $$ = new ParserVal($1.dval - $3.dval); } 
| exp '*' exp { $$ = new ParserVal($1.dval * $3.dval); } 
| exp '/' exp { $$ = new ParserVal($1.dval/$3.dval); } 
| '-' exp %prec NEG { $$ = new ParserVal(-$2.dval); } 
| exp '^' exp { $$ = new ParserVal(Math.pow($1.dval, $3.dval)); } 
| '(' exp ')' { $$ = $2; } 
; 
%% 

String ins; 
StringTokenizer st; 

void yyerror(String s) 
{ 
System.out.println("par:"+s); 
} 

boolean newline; 
int yylex() 
{ 
String s; 
int tok; 
Double d; 
//System.out.print("yylex "); 
if (!st.hasMoreTokens()) 
if (!newline) 
{ 
newline=true; 
return '\n'; //So we look like classic YACC example 
} 
else 
return 0; 
s = st.nextToken(); 
//System.out.println("tok:"+s); 
try 
{ 
d = Double.valueOf(s);/*this may fail*/ 
yylval = new ParserVal(d.doubleValue()); //SEE BELOW 
tok = NUM; 
} 
catch (Exception e) 
{ 
tok = s.charAt(0);/*if not float, return char*/ 
} 
return tok; 
} 

void dotest() 
{ 
BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 
System.out.println("BYACC/J Calculator Demo"); 
System.out.println("Note: Since this example uses the StringTokenizer"); 
System.out.println("for simplicity, you will need to separate the items"); 
System.out.println("with spaces, i.e.: '(3 + 5) * 2'"); 
while (true) 
{ 
System.out.print("expression:"); 
try 
{ 
ins = in.readLine(); 
} 
catch (Exception e) 
{ 
} 
st = new StringTokenizer(ins); 
newline=false; 
yyparse(); 
} 
} 

public static void main(String args[]) 
{ 
Parser par = new Parser(false); 
par.dotest(); 
} 

回答

0

我忘記了yacc(OPS)中的尾遞歸,但以下內容似乎是一種簡化。

OPS: OP RESTOPS 
; 

RESTOPS: OPS 
|  
; 

OP: '{' OPS '}' 
|  IF '(' EXPR ')' OP ELSEOP 
|  WHILE '(' EXPR ')' OP 
|  EXIT ';' 
|  EXPR ';' 
; 

ELSEOP: ELSE OP 
| 
; 
+0

那麼EXPR定義呢? – Anatoly

+0

我有點出yacc。你正在深入嵌套非終結者。和RESTOPS/ELSEOP一樣,我會用運算符EXPR嘗試RESTEXPR,或者清空。 –

1

它看起來像你有你的.Y文件中的兩個獨立的語法:PROGRAMinput。由於沒有%start指令,因此第一個(PROGRAM)被視爲您的語法,並且由於該語法永遠不會指向input或其後的任何符號,它們都是無用的 - 它們在解析PROGRAM時永遠不會減少。

你的文件只能有一個語法 - 刪除(或註釋掉)不需要的語法。