2013-05-01 22 views
1

讓我們假設我有一個簡單的JavaCC語法解析加法和減法:的JavaCC:我怎樣才能維持原來的文本(包括空格)


.... 
void CompilationUnit() : 
{} 
{ 
    (Expression())+ 
    EOF 
} 
void Expression() : 
{} 
{ 
    Number() 
    (
    Addition() 
    | Subtraction() 
)* 
} 
void Number() : 
{} 
{ 
    
} 
void Addition() : 
{} 
{ 
    Number() 
} 
void Subtraction() : 
{} 
{ 
    Number() 
} 

我有使用該語法產生的AST類以計算結果:


public class Calculator extends DepthFirstVisitor { 
    int result = -1; 
    public void visit(Expression n) { 
    if (result >= 0) System.out.println(toText(n) + " = " + result); 
    result = 0; 
    super.visit(n); 
    } 
    public void visit(Number n) { 
    ... 
    } 
    public void visit(Addition n) { 
    ... 
    } 
    .... 
} 

我能夠計算表達式的值,但我也需要原始表達式(因爲它出現了)。所以以下輸入:

 
    5 + 2 - 1 
    2 + 1 

我想有以下輸出:

 
5 + 2 - 1 = 6 
2 + 1 = 3 

不幸的是,因爲我喜歡跳過空格或換行符角色,這是我得到的是:

 
5+2-1 = 6 
2+1 = 3 

有沒有什麼方法可以輸出原始文本(包括跳過的字符)?

請注意實際問題要大得多,語法要複雜得多。所以我沒有真正尋找特定於上述問題的解決方案(例如,預處理行並將它們拆分爲換行符或修改方法以在每個令牌後面「手動」添加空格),但更像是使用某些JavaCC功能的解決方案。

回答

2

ANTLr和Xtext都支持空白和註釋的「隱藏標記」。請參閱here以獲得一些提示,或者使用Google。也許JavaCC有一些相似的概念。

編輯:JavaCC似乎使用術語「特殊令牌」。見here for some details

+0

是的JavaCC有特殊的標記。請參閱http://www.engr.mun.ca/~theo/JavaCC-FAQ/常見問題中的Q 5.2。 – 2013-05-01 23:22:23

0

基本上你不能在編譯器中做到這一點。您必須在語法中將空格作爲標記捕獲,並允許它在任何地方被允許使用,而且這種語法無處不在,而且所產生的語法會非常複雜以至於無法執行或甚至無法生成。你必須做的是捕獲對實體來自的源代碼(行和列)中的座標的引用:例如可能是當前行和列號的文本。

編譯器的行爲方式是有原因的。

+0

JavaCC(以及許多其他解析器生成器)使得這種操作非常容易,不會增加複雜性,從而破壞了您的答案。 – 2013-05-01 23:25:33