我正在尝试为简单的语言编写解析器,但我到了不知道如何处理这个问题的地步。这是my.jj文件
options
{
STATIC = false;
LOOKAHEAD=2;
//DEBUG_LOOKAHEAD = true;
DEBUG_TOKEN_MANAGER=true;
FORCE_LA_CHECK = true;
DEBUG_PARSER = true;
JDK_VERSION = "1.7";
}
PARSER_BEGIN(Parser)
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class Parser{
private static BufferedWriter bufferFileWriter;
private static FileWriter fWriter;
public static void main(String args []) throws ParseException, IOException
{
Parser parser = new Parser(System.in);
fWriter = new FileWriter("result", true);
bufferFileWriter = new BufferedWriter(fWriter);
parser.program();
// TO DO
}
}
PARSER_END(Parser)
SKIP :
{
" "
| "\r"
| "\t"
| "\n"
}
TOKEN : /* OPERATORS */
{
< PLUS : "+" >
| < MINUS : "-" >
| < MULTIPLY : "*" >
| < DIVIDE : "/" >
| < MODULO : "%" >
| < ASSIG : ":=" >
| < EQUAL : "==" >
| < DIFF : "!=" >
| < SMALLER : "<" >
| < GRATER : ">" >
| < S_OR_EQU: "<=" >
| < G_OR_EQU: "=>" >
}
TOKEN : /*KEY WORDS FROM LANGUAGE */
{
< VAR: "VAR">
| < BEGIN : "BEGIN" >
| < END : "END" >
| < IF : "IF" >
| < ELSE : "ELSE" >
| < THEN : "THEN" >
| < WHILE: "WHILE" >
| < DO : "DO" >
| < READ : "READ" >
| < WRITE : "WRITE" >
| < SEMICOL : ";" >
}
TOKEN :
{
< VALUE : < ID > | < NUMBER > >
| < NUMBER : (< DIGIT >)+ >
| < #DIGIT : [ "0"-"9" ] >
| < ID : (["a"-"z"])+ >
}
void program():
{}
{
varDeclarations()< BEGIN > commands() < END >
}
void varDeclarations():
{}
{
< VAR >
{
System.out.println("past VAR token");
}
(< ID >
)+
}
void commands():
{}
{
(LOOKAHEAD(3)
command())+
}
void command():
{
Token t;
}
{
assign()
|< IF >condition()< THEN >commands()< ELSE >commands()< END >
|< WHILE >condition()< DO >commands()< END >
|< READ >
t=< ID >
{
try
{
fWriter.append("LOAD "+t.image);
System.out.println("LOAD "+t.image);
}
catch(IOException e)
{
};
}
< SEMICOL >
|< WRITE >
t = < VALUE >< SEMICOL >
}
void assign():
{
Token t;
}
{
t=< ID >
{
}
< ASSIG >expression(t)< SEMICOL >
}
void condition():
{}
{
< VALUE > condOperator() < VALUE >
}
void condOperator():
{}
{
< EQUAL > | < DIFF > | < SMALLER > | < S_OR_EQU > | < GRATER > | < G_OR_EQU >
}
Token operator():
{
Token tok;
}
{
tok=< PLUS >
{
System.out.println(tok.image);
return tok;
}
|tok=< MINUS >
{
System.out.println(tok.image);
return tok;
}
|tok=< MULTIPLY >
{
System.out.println(tok.image);
return tok;
}
|tok=< DIVIDE >
{
System.out.println(tok.image);
return tok;
}
|tok=< MODULO >
{
System.out.println(tok.image);
return tok;
}
}
void expression(Token writeTo):
{
Symbol s;
Token t1, t2, t3;
}
{
t1 = < VALUE >
t2 = operator()
t3 = < VALUE >
< SEMICOL >
{
if(t2.image.equals("+"))
{
try
{
fWriter.append("ADD "+t1.image+" "+t2.image);
System.out.println("ADD "+t1.image+" "+t2.image);
}catch(IOException e)
{
}
}
}
}
此刻写入文件并不重要。
这是我要解析的文字:
VAR
a b
BEGIN
READ a ;
READ b ;
WHILE a != b DO
IF a < b THEN (* a <-> b *)
a := a + b ;
b := a - b ;
a := a - b ;
ELSE
END
a := a - b ;
END
WRITE a ;
END
这是我从调试器获得的输出:
mother-ship $ java Parser test
Call: program
Call: varDeclarations
正如您所见,解析器输入了varDeclaration方法,但为什么他不能将令牌与单词VAR匹配? 我会感激任何帮助。
@Theodore我按照你的建议做了但是没有用。也许我正在以错误的方式编译和执行程序? 这是我的控制台的副本:
$javacc Parser.jj
Java Compiler Compiler Version 5.0 (Parser Generator)
(type "javacc" with no arguments for help)
Reading from file Parser.jj . . .
File "TokenMgrError.java" is being rebuilt.
File "ParseException.java" is being rebuilt.
File "Token.java" is being rebuilt.
File "SimpleCharStream.java" is being rebuilt.
Parser generated successfully.
$ javac *.java
$ java Parser VAR a
Call: program
Call: varDeclarations
答案 0 :(得分:1)
让解析器识别“VAR”关键字没问题。问题是“a”被标记为“VALUE”标记,而解析器期望“VAR”关键字后面的“ID”标记。 (参见下面的输入和输出。)
VALUE' has precedence over the rule for
ID`的规则因为是第一个。 (参见FAQ中的问题3.3。)
您可能应该执行的操作是使用以下规则替换VALUE
的{{1}}规则。
void Value() : {} { <ID> | <NUMBER> }
输入:
VAR
a
输出:
Call: program
Call: varDeclarations
Current character : V (86) at line 1 column 1
Possible string literal matches : { "VAR" }
Current character : A (65) at line 1 column 2
Possible string literal matches : { "VAR" }
Current character : R (82) at line 1 column 3
No more string literal token matches are possible.
Currently matched the first 3 characters as a "VAR" token.
****** FOUND A "VAR" MATCH (VAR) ******
Consumed token: <"VAR" at line 1 column 1>
past VAR token
Skipping character : \n (10)
Current character : a (97) at line 2 column 1
No string literal matches possible.
Starting NFA to match one of : { <VALUE> }
Current character : a (97) at line 2 column 1
Currently matched the first 1 characters as a <VALUE> token.
Possible kinds of longer matches : { <VALUE>, <ID> }
Current character : \n (10) at line 2 column 2
Currently matched the first 1 characters as a <VALUE> token.
Putting back 1 characters into the input stream.
****** FOUND A <VALUE> MATCH (a) ******
Return: varDeclarations
Return: program
Exception in thread "main" tokenNotMatched.ParseException: Encountered " <VALUE> "a "" at line 2, column 1.
Was expecting:
<ID> ...