首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Lemon Parser Generator中的歧义语法

Lemon Parser Generator中的歧义语法
EN

Stack Overflow用户
提问于 2011-10-10 09:26:55
回答 1查看 896关注 0票数 2

因此,基本上我希望使用PEAR包PHP_LexerGenerator和PHP_ParserGenerator生成的词法分析器/解析器来解析PHP中的结构化CSS代码。我的目标是像这样解析文件:

代码语言:javascript
复制
selector, selector2 {
    prop: value;
    prop2 /*comment */ :
       value;

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

只要我没有伪类,这一切都很好。伪类允许它向元素添加:和CSS名称([a-z][a-z0-9]*),就像在a.menu:visited中一样。由于有点懒惰,解析器没有有效伪类的列表,并接受类名的所有内容。

我的语法(忽略所有特例和空格)如下所示:

代码语言:javascript
复制
document   ::= (<rule>)*

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

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

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

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

现在,当我尝试解析以下代码时

代码语言:javascript
复制
h1 {
    test:visited {
        simple: case;
    }
}

解析器抱怨说,它预期双冒号后面会有一个<name>。因此,它尝试将simple:读取为<selector> (只需查看So的语法突出显示)。

解析器不能进行足够的回溯来尝试<definition>规则,这是我的错误吗?还是Lemon还不够强大,不足以表达这一点?如果是这样,我该怎么做才能让解析器使用这个语法呢?

EN

回答 1

Stack Overflow用户

发布于 2011-10-10 12:25:45

您的问题是关于PHP_ParserGeneratorPHP_LexerGenerator的。解析器生成器代码被标记为“未维护”,这是不好的预兆。

您用于语法的语法对于Lemon是不可接受的,因此您需要澄清为什么您认为解析器生成器应该接受它。你提到了一个问题,‘期望<name>跟在双冒号后面,但你的语法和样本输入都没有双冒号,这让你很难帮上忙。

我认为这个Lemon语法等同于你展示的那个:

代码语言:javascript
复制
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.

但是,在编译时,Lemon会报错1 parsing conflicts,输出文件显示:

代码语言:javascript
复制
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‘部分,也可能是’定义‘的一部分:

代码语言:javascript
复制
name1:name4 : name2:name3 ;

你的意思是允许这样的语法吗?名义上,根据语法,这应该是有效的,但是

代码语言:javascript
复制
name1:name4;

也应该是有效的。我认为需要2到3个先行标记来消除这些歧义(所以您的语法不是LALR(1),而是LALR(3))。

特别回顾一下你对“选择器”的定义。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7707733

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档