2010-09-27 74 views
4

什麼JavaCC的語法確實實現語法,可以分析這些類型的線路:如何匹配JavaCC中的可選打開/關閉標籤?

[b]content[/b] 
content[/b] 
[b]content 

雖然JavaCC解析器需要分析所有的行,就必須區分正確和不正確標記行爲。

正確標記就像第一行一樣,它們有一個打開和關閉標記。當標籤匹配時,這將輸出一個粗體格式的文本。

不正確的標籤就像第2行和第3行,它們沒有匹配的打開或關閉標籤。當這些發生時,它們按原樣寫入輸出,不會被解釋爲標籤。

我試過下面的JavaCC代碼(LOOKAHEAD = 999999)。問題是,這種語法將總是作爲invalidTag()而不是bold()匹配所有內容。我怎樣才能確保JavaCC解析器在任何時候都可以匹配bold()

String parse() : 
{} 
{ 
    body() <EOF> 
    { return buffer; } 
} 

void body() : 
{} 
{ 
    (content())* 
} 

void content() : 
{} 
{ 
    (text()|bold()|invalidTag) 
} 

void bold() : 
{} 
{ 
    { buffer += "<b>"; } 
    <BOLDSTART>(content())*<BOLDEND> 
    { buffer += "</b>"; } 
} 

void invalidTag() : 
{ 
} 
{ 
    <BOLDSTART> | <BOLDEND> 
    { // todo: just output token 
    } 
} 

TOKEN : 
{ 
    <TEXT : (<LETTER>|<DIGIT>|<PUNCT>|<OTHER>)+ > 
    |<BOLDSTART : "[b]" > 
    |<BOLDEND : "[/b]" > 

    |<LETTER : ["a"-"z","A"-"Z"] > 
    |<DIGIT : ["0"-"9"] > 
    |<PUNCT : [".", ":", ",", ";", "\t", "!", "?", " "] > 
    |<OTHER : ["*", "'", "$", "|", "+", "(", ")", "{", "}", "/", "%", "_", "-", "\"", "#", "<", ">", "=", "&", "\\"]  > 
} 
+0

* Sees BBCode * ... * [Pukes](http://stackoverflow.com/questions/3788959/regex-to-split-bbcode-into-pieces/3792262#3792262)* – NullUserException 2010-10-07 06:15:56

+0

@NullUserException:Doesn' t爲我工作,我需要解析所有可能的BBCode標記人員可以輸入。 – Kdeveloper 2010-10-07 12:31:29

回答

5

您的語法不明確。這可能不是你的錯,因爲它可能很難爲你正在嘗試解決的問題產生一個明確的語法。

LL(k)解析器可能不是這份工作的最佳工具。

但是,標記器可能是有用的,並且使用堆棧來查找匹配和不匹配的標記對可能是合適的選擇。

+0

我得出了同樣的結論,但我發現JavaCC只是一個標記器的矯枉過正。你知道100%的Java tokenizer嗎? (所以我不需要額外的構建工具?) – Kdeveloper 2010-10-07 12:34:39

2

前段時間我已經瞭解到,一些簡單的問題可以很容易地在語義或詞法層面上解決,而在句法層面證明是非常困難或不可能的。

注意:我對JavaCC不太熟悉,但過去我一直使用多個編譯器生成器(我最喜歡的是sablecc)。

你很可能只是定義你的「內容」是這樣的:

(text()|boldstart()|boldend()|invalidTag) 

凡BOLDSTART()將只是一味的輸出開始標籤和BOLDEND() - 結束標籤。

如果要過濾掉所有這些,只生成正確結束的標籤,那麼我會建議爲此創建某種有狀態的自動機,給它打開和結束標籤,注意是否應該啓動粗體,停止或繼續(可能包括嵌套深度),並根據輸出開始,停止或沒有標籤。與使用JavaCC中的語法或詞法分析工具相比,這將非常容易實現。

+0

謝謝,你有鏈接太多的例子嗎?或者知道一個Java tokenizer工具? – Kdeveloper 2010-10-07 12:37:08