2013-06-05 120 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