2013-06-05 59 views
0

我想写一个简单的语言的解析器,我到了我不知道如何处理这个问题的地步。这里是my.jj文件JavaCC令牌不匹配

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

使用选项DEBUG_TOKEN_MANAGER =真,向我们展示的结果。此外,如果您可以发布链接到完整的jj文件,这将有所帮助。 –

+0

嗨,我编辑了我的问题并粘贴我的.jj文件。感谢您的关注。 –

回答

1

我没有问题,让你的解析器承认“VAR”关键字。问题在于,“a”被标记为“VALUE”标记,而解析器期望在“VAR”关键字之后有一个“ID”标记。 (请参阅下面的输入和输出。)

该规则为VALUE' has precedence over the rule for ID`凭借第一。 (请参见FAQ中的问题3.3)

您可能应该做的是用以下规则替换现在使用的规则VALUE

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> ... 
+0

对不起,在你的答案下没有评论,但迷你Markdown编辑正在杀死我。我发现编辑我的问题更容易,结果也更容易阅读。 –

+0

没问题。它在我看来你是在命令行上输入输入('VAR a')。尝试通过'java Parser

+0

我觉得即使双面facepalm是不够的。你是对的。早些时候,我用$ java解析器testFile运行它,而我应该这样做$ java Parser