2011-10-10 68 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'的定义。