2012-02-08 54 views
0

雖然PLY有問題,但我嘗試在野牛中重寫相同的語法片段並遇到類似的問題。這表明我可能做錯了什麼。野牛匹配錯誤標記

語法片段的符號表示如下:

document -> fragment? 
fragment -> { \n line* \n fragment? } 
line  -> [^\n]+ \n 

相關法線:

[{}] return *yytext; 
[^\n]+ return ANYTHING; 
\n  return EOL; 

相關野牛行:

multiline: '{' EOL lines EOL multiline '}' 
     | 
     ; 

lines: lines ANYTHING EOL 
    | 
    ; 

語法是確定性的,儘管我知道甚至應該是LALR(1)(雖然沒有真正嘗試構建畫面)。像"{\n\n}"這樣的文檔解析好,但multiline元素嵌套的文檔(例如"{\n\n{\n\n}}")沒有,詞法分析器將最後一個"}}"看作標記"ANYTHING"而不是兩個'}' s。

我在做什麼錯?

+0

你試過'[^ {} \ n] + return ANYING;'? – wildplasser 2012-02-08 13:10:25

+0

這是一個可行的方法,但將文本分隔爲「行」的原始思想是允許任何非EOL字符進入字段。 – mistotebe 2012-02-08 13:48:46

+1

那麼會吃掉你所有的「{}」,不是嗎? Lex是貪婪的:如果兩個模式匹配當前輸入,最長匹配獲勝。 – wildplasser 2012-02-08 14:05:54

回答

3
[{}] return *yytext; 
[^{}\n]+ return ANYTHING; 
\n  return EOL; 

Lex是貪婪的:如果兩個模式匹配當前輸入,最長匹配獲勝。在原始的lex片段中,[^\n]+模式在其中捕獲了帶有{}的行。

+0

是的,這是一個解決方案,限制'ANYTHING'不要與*任何其他詞位(yuck!)發生衝突,並添加一個非終結符ANYTHING_,將它們全部組合在一起......是否有可能設置詞法分析狀態足夠可靠地擁有一個只有在正確的地方觸發的「任何」的詞義? – mistotebe 2012-02-09 10:55:24

+0

我不明白你的意思。如果你想讓任何東西匹配除\ n和{}之外的任何東西,那麼否定的字符類就是要走的路(它有什麼問題?)。如果你想{}保存(例如在字符串或註釋中),那麼你可能需要啓動條件。 (或手動創建詞法分析器,因爲它看起來很簡單) – wildplasser 2012-02-09 11:06:43

+0

它只是[this](http://mistotebe.net/image/grammar.txt)的一個片段,還有其他詞位和指定ANYTHING令牌的方式會變得很乏味。那些起始條件是什麼? – mistotebe 2012-02-09 12:26:26