css - Lemon Parser Generator 的二义性语法

标签 css parsing lemon

所以基本上我想使用 PEAR 包 PHP_LexerGenerator 和 PHP_ParserGenerator 生成的词法分析器/解析器来解析 PHP 中的结构 CSS 代码。我的目标是解析这样的文件:

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> 是我的错误吗?规则?或者柠檬的力量不足以表达这一点?如果是这样,我该怎么做才能让解析器使用这个语法?

最佳答案

您的问题涉及 PHP_ParserGeneratorPHP_LexerGenerator 。解析器生成器代码被标记为“未维护”,这预示着不好。

您用于语法的语法对于 Lemon 来说是 Not Acceptable ,因此您需要澄清为什么您认为解析器生成器应该接受它。您提到了“预期 <name>”的问题遵循双冒号,但您的语法和示例输入都没有双冒号,这使得很难帮助您。

我认为这个 Lemon 语法与您展示的语法等效:

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输出文件显示:

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))。

特别检查您对“选择器”的定义。

关于css - Lemon Parser Generator 的二义性语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7707733/

相关文章:

android - 带有不可编辑/不可取消后缀的 EditText

Python字符串范围(解析html)

jquery 显示/隐藏带有直接链接的 Div

java - 如何获得一个实际的单词迭代器包装breakIterator?

css - 无法单击 chrome 上的单选按钮

c - 使用 flex-lexer 和 cmake 构建错误

c - 错误是在语法中还是在代码中?

Lemon 中 token 析构函数的自定义释放函数

javascript - VueJs - 通过过渡更改 div 颜色

javascript - 如何溢出自动聚焦最后一个元素