我一直在尝试制作一个从lexer(jflex(中获取令牌的解析器,并使用Java和bison作为解析器。以下是我迄今为止为解析器编写的代码:
%define api.prefix {EXAMPLE}
%define api.parser.class {EXAMPLE}
%define api.parser.public
%define parse.error verbose
%code imports{
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.IOException;
}
%code {
public static void main(String args[]) throws IOException {
EXAMPLELexer lexer = new EXAMPLELexer(System.in);
EXAMPLE parser = new EXAMPLE(lexer);
if(parser.parse()){
System.out.println("VALID FROM PARSER");
}
else{
System.out.println("ERROR FROM PARSER");
}
return;
}
}
/* Bison Declarations */
%token <Integer> NUM
%type exp
%%
input: line | input line;
line: 'n'
| exp 'n' { System.out.println($exp); }
| error 'n'
;
exp:
NUM { $$ = $1; }
| exp '=' exp { if ($1.intValue() != $3.intValue()) yyerror("calc: error: " + $1 + " != " + $3); }
| exp '+' exp { $$ = $1 + $3; }
| exp '-' exp { $$ = $1 - $3; }
| exp '*' exp { $$ = $1 * $3; }
| exp '/' exp { $$ = $1 / $3; }
| '-' exp %prec NEG { $$ = -$2; }
| exp '^' exp { $$ = (int) Math.pow($1, $3); }
| '(' exp ')' { $$ = $2; }
| '(' error ')' { $$ = 1111; }
| '!' { $$ = 0; return YYERROR; }
| '-' error { $$ = 0; return YYERROR; }
%%
class EXAMPLELexer implements EXAMPLE.Lexer {
InputStreamReader it;
Yylex yylex;
public EXAMPLELexer(InputStream is){
it = new InputStreamReader(is);
yylex = new Yylex(it);
}
@Override
public void yyerror (String s){
}
@Override
public Object getLVal() {
return null;
}
@Override
public int yylex () throws IOException{
return yylex.yylex();
}
}
当我尝试使用jflex和bison命令时,我会得到以下信息:"exp"的$$没有声明类型,与$1、$3 相同
请帮帮我,我已经被困了一段时间了!(附言:我已经尝试过%union{},但它只会导致更多错误。不幸的是,如果你有任何实际使用它的示例代码,我很想学习,因为似乎缺乏Java和使用Jflex的bison的文档。(
exp没有声明类型。此外,未声明令牌NEG。
%token <String> NEG
%type<Object> exp
lexer接口需要在%code lexer{};中声明;块,位于%%parser结束标记之前。
下面是你的文件示例,这里是示例.y
%language "Java"
%define api.prefix {EXAMPLE}
%define api.parser.class {EXAMPLE}
%define api.parser.public
%define parse.error verbose
%code imports{
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.IOException;
}
%code {
public static void main(String args[]) throws IOException {
EXAMPLELexer lexer = new EXAMPLELexer(System.in);
EXAMPLE parser = new EXAMPLE(lexer);
if(parser.parse()){
System.out.println("VALID FROM PARSER");
}
else{
System.out.println("ERROR FROM PARSER");
}
return;
}
}
/* Bison Declarations */
%token <Integer> NUM
%token <String> NEG
%type<Object> exp
%%
input: line | input line;
line: 'n'
| exp 'n' { System.out.println($exp); }
| error 'n'
;
exp:
NUM { $$ = Integer.parseInt($1); }
| exp '=' exp { if ($1.intValue() != $3.intValue()) yyerror("calc: error: " + $1 + " != " + $3); }
| exp '+' exp { $$ = $1 + $3; }
| exp '-' exp { $$ = $1 - $3; }
| exp '*' exp { $$ = $1 * $3; }
| exp '/' exp { $$ = $1 / $3; }
| '-' exp %prec NEG { $$ = -$2; }
| exp '^' exp { $$ = (int) Math.pow($1, $3); }
| '(' exp ')' { $$ = $2; }
| '(' error ')' { $$ = 1111; }
| '!' { $$ = 0; return YYERROR; }
| '-' error { $$ = 0; return YYERROR; }
%code lexer {
private EXAMPLELexer lexer;
private Object yylval;
public YYLexer (EXAMPLELexer elexer)
{
lexer = elexer;
}
@Override
public void yyerror (String s) {
}
@Override
public Object getLVal() {
return yylval;
}
@Override
public int yylex () throws IOException {
int v = lexer.scan();
yylval = lexer.getValue();
return v;
}
};
%%
这是一个例子的开始。jf
import java.util.*;
import java.io.InputStreamReaader;
import static EXAMPLE.*;
%%
%class EXAMPLELexer
%integer
%unicode
%{
EXAMPLELexer(InputStream ios) {
this (new InputStreamReader(ios));
}
String lexeme;
private void setValue(String val)
{
lexeme = val;
}
public String getValue()
{
return lexeme;
}
%}
INTNUM = ([0-9]*)
%%
{INTNUM} { setValue( yytext() ); return EXAMPLE.Lexer.NUM; }