Java Bjacc/j中频和中频定义
所以我对byacc/j中的if-then-else和while定义有一个问题。有人能帮忙吗?输入。y在下面。我无法理解yacc错误。很明显,12条规则从未减少,但我该怎么做Java Bjacc/j中频和中频定义,java,yacc,Java,Yacc,所以我对byacc/j中的if-then-else和while定义有一个问题。有人能帮忙吗?输入。y在下面。我无法理解yacc错误。很明显,12条规则从未减少,但我该怎么做 %{ import java.lang.Math; import java.io.*; import java.util.StringTokenizer; %} /* YACC Declarations */ %token NUM %left '-' '+' %left '*' '/' %left NEG /* negat
%{
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();
}
%{
导入java.lang.Math;
导入java.io.*;
导入java.util.StringTokenizer;
%}
/*YACC声明*/
%令牌数
%左''''+'
%左'*''/'
%左负/*否定——一元负*/
%右“^”/*幂运算*/
%退出时,如果没有,则标记
%代币均衡器
%令牌字符串NUM ID
%%
节目:老年退休金计划
;
行动:行动
|行动
;
OP1:“{OPS'}”
|EXPR';'
|如果“(“EXPR”)”OP1,则为其他OP1
|而“('EXPR')”OP1
|退出“;”
;
OP2:IF'('EXPR')OP
|如果“(“EXPR”)”OP1或OP2
|而“('EXPR')”OP2
;
OP:OP1 | OP2;
EXPR:EXPR1
|ID“=”表达式
EXPR1:EXPR2
|EXPR1 EQ EXPR2
|EXPR1-LE EXPR2
|EXPR1 GE EXPR2
|EXPR1 NE EXPR2
|EXPR1'>'EXPR2
|EXPR1'我已经忘记了yacc(OPS)中的尾部递归,但是下面似乎是一个简化
OPS: OP RESTOPS
;
RESTOPS: OPS
|
;
OP: '{' OPS '}'
| IF '(' EXPR ')' OP ELSEOP
| WHILE '(' EXPR ')' OP
| EXIT ';'
| EXPR ';'
;
ELSEOP: ELSE OP
|
;
我已经忘记了yacc(OPS)中的尾部递归,但是下面似乎是一个简化
OPS: OP RESTOPS
;
RESTOPS: OPS
|
;
OP: '{' OPS '}'
| IF '(' EXPR ')' OP ELSEOP
| WHILE '(' EXPR ')' OP
| EXIT ';'
| EXPR ';'
;
ELSEOP: ELSE OP
|
;
在.y文件中似乎有两个独立的语法:程序
和输入
。由于没有%start
指令,因此第一个(程序
)将作为您的语法,并且由于该语法从未引用输入
或其后的任何符号,因此它们都是无用的——在解析程序
时,它们永远无法减少
您的文件中只能有一个语法--删除(或注释掉)不需要的语法。您的.y文件中似乎有两个独立的语法:程序
和输入
。由于没有%start
指令,因此第一个(程序
)将作为您的语法,并且由于该语法从未引用输入
或其后的任何符号,因此它们都是无用的——在解析程序
时,它们永远无法减少
您的文件中只能有一个语法——删除(或注释掉)不需要的语法。那么EXPR定义呢?我有点不懂yacc。您正在对非终结符进行深度嵌套。与RESTOPS/ELSEOP一样,我会尝试使用带有运算符EXPR的RESTEXPR,或者是空的。那么EXPR定义呢?我有点不懂yacc。您正在对非终结符进行深度嵌套。与RESTOPS/ELSEOP一样,我会使用操作符EXPR尝试RESTEXPR,或者使用empty。