2011-10-10 66 views
2

所以基本上我想在PHP中使用由PEAR包生成的詞法分析器/解析器PHP_LexerGenerator和PHP_ParserGenerator來解析結構CSS代碼。我的目標是解析這樣的文件:Lemon Parser Generator的模糊語法

selector, selector2 { 
    prop: value; 
    prop2 /*comment */ : 
     value; 

    subselector { 
     prop: value; 
     subsub { prop: value; } 
    } 
} 

只要我沒有僞類,這就好了。僞類允許它向元素添加:和CSS名稱([a-z][a-z0-9]*),如a.menu:visited。有點懶,解析器沒有有效的僞類列表,並接受類名的所有內容。

我的語法(忽略所有的特殊情況和空格)如下:

document ::= (<rule>)* 

rule  ::= <selector> '{' (<content>)* '}' 

content ::= <rule> 
content ::= <definition> 

definition ::= <name> ':' <name> ';' 

//    h1  .class.class2#id :visited 
<selector> ::= <name> (('.'|'#') <name>)* (':' <name>)? 

現在,當我試圖解析以下

h1 { 
    test:visited { 
     simple: case; 
    } 
} 

解析器抱怨,它預期<name>遵循雙冒號。所以它試圖讀取simple:作爲<selector>(看看SO的語法突出顯示)。

是我的錯誤,解析器不能回溯到足以嘗試<definition>規則?還是檸檬只是沒有足夠強大來表達這一點?如果是這樣,我能做些什麼來獲得解析器使用這個語法?

+0

你的語法不會處理'select1,select2 {...}'表示法。沒有規則處理'以逗號分隔的選擇器列表'。 –

+1

你的問題提到'雙冒號',但在示例輸入中沒有'::',也沒有任何處理語法中的雙冒號的東西。 –

回答

3

您的問題詢問了有關PHP_ParserGeneratorPHP_LexerGenerator。解析器生成器代碼被標記爲「未維護」,這代表生病。

您用於語法的語法對檸檬來說是不可接受的,所以您需要闡明爲什麼您認爲解析器生成器應該接受它。你提到'預計<name>跟隨雙冒號的問題,但是你的語法和你的樣本輸入都沒有雙冒號,這很難幫助你。

我覺得這檸檬語法相當於一個你表明:

document  ::= rule_list. 
rule_list  ::= . 
rule_list  ::= rule_list rule. 
rule   ::= selector LBRACE content_list RBRACE. 
content_list ::= . 
content_list ::= content_list content. 
content   ::= rule. 
content   ::= definition. 
definition  ::= NAME COLON NAME SEMICOLON. 
selector  ::= NAME opt_dothashlist opt_colonname. 
opt_dothashlist ::= . 
opt_dothashlist ::= dot_or_hash NAME. 
dot_or_hash  ::= DOT. 
dot_or_hash  ::= HASH. 
opt_colonname ::= COLON NAME. 

然而,當它被編譯,檸檬抱怨1 parsing conflicts和輸出文件顯示:

State 2: 
      definition ::= NAME * COLON NAME SEMICOLON 
      selector ::= NAME * opt_dothashlist opt_colonname 
    (10) opt_dothashlist ::= * 
      opt_dothashlist ::= * dot_or_hash NAME 
      dot_or_hash ::= * DOT 
      dot_or_hash ::= * HASH 

         COLON shift 10 
         COLON reduce 10 ** Parsing conflict ** 
          DOT shift 13 
          HASH shift 12 
       opt_dothashlist shift 5 
        dot_or_hash shift 7 

這意味着不知道如何處理冒號;這可能是一個「選擇」的「opt_colonname」的一部分,也可能是一個「定義」的一部分:

name1:name4 : name2:name3 ; 

您的意思是允許的語法如?名義上,根據語法,這應該是有效的,但

name1:name4; 

也應該是有效的。我認爲它需要2或3個前視標記來消除這些歧義(因此,您的語法不是LALR(1)而是LALR(3))。

特別回顧'selector'的定義。