代码之家  ›  专栏  ›  技术社区  ›  Erik van Brakel scottrakes

使用ANTLR边缘情况解析CSS

  •  9
  • Erik van Brakel scottrakes  · 技术社区  · 16 年前

    我试图使用ANTLR解析CSS,或者至少是基本的CSS。不过,我的lexer规则遇到了一些问题。问题在于ID选择器和十六进制颜色值之间的歧义。为了清楚起见,使用简化的语法,考虑以下输入:

    #bbb {
      color: #fff;
    }
    

    以及以下解析器规则:

    ruleset : selector '{' property* '}';
    selector: '#' ALPHANUM;
    property: ALPHANUM ':' value ';' ;
    value: COLOR;
    

    这些lexer令牌:

    ALPHANUM : ('a'..'z' | '0'..'9')+;
    COLOR : '#' ('0'..'9' | 'a'..'f')+;
    

    任何帮助都将不胜感激!


    解决方案:原来我在语法方面做得太多了,我可能应该在使用AST的代码中处理这些问题。CSS有太多不明确的标记,无法可靠地拆分为不同的标记,所以我现在使用的方法基本上是标记像“#”这样的特殊字符。',':'和花括号,并在消费者代码中进行后处理。效果更好,处理边缘情况也更容易。

    4 回复  |  直到 15 年前
        1
  •  8
  •   Walt W    16 年前

    LLETTERS: ( 'a'..'z' )
    ULETTERS: ( 'A'..'Z' )
    NUMBERS: ( '0'..'9' )
    HASH : '#';
    

    然后,在解析器规则中,您可以这样做:

    color: HASH (LLETTERS | ALPHANUM)+;
    selector: HASH (ULETTERS | LLETTERS) (ULETTERS | LLETTERS | NUMBERS)*;
    

    这允许您在语法上指定差异,大致可以用上下文来描述,而在词汇上,大致可以通过外观来描述。如果某物的含义因位置而异,那么这种差异应该在语法中指定,而不是在词法中指定。

    请注意,颜色和选择器的定义完全相同。词法分析器通常是将输入字符串转换为语法的模块的一个单独阶段,因此使用模糊的词典是无效的(正如所指出的,bbb可以是十六进制,也可以是小写字母字符串)。因此,数据有效性检查需要在其他地方进行。

        2
  •  2
  •   ChrisW    16 年前

    正如沃尔特所说, Appendix G. Grammar of CSS 2.1 对莱克斯说 HASH ,然后(取决于其相对于其他令牌的位置)解析 哈希 要么作为a simple_selector 或作为a hexcolor .

    词法分析器定义了以下标记。..

    "#"{name}       {return HASH;}
    

    …语法包括以下规则。..

    hexcolor
      : HASH S*
      ;
    
    simple_selector
      : element_name [ HASH | class | attrib | pseudo ]*
      | [ HASH | class | attrib | pseudo ]+
      ;
    

    这意味着基于语法的解析器将允许非十六进制hexcolor。

    稍后,我会在分析/解释词法分析+解析语法树的代码中检测到非十六进制hexcolor。

        3
  •  0
  •   ЯegDwight kri    13 年前

    为了从多个备选方案中做出决定,ANTLR有两个选择,

    • 句法谓词
    • 语义谓词

    这是来自antlr语法库(css2.1 g):

    simpleSelector
        : elementName 
            ((esPred)=>elementSubsequent)*
    
        | ((esPred)=>elementSubsequent)+
        ;
    
    esPred
        : HASH | DOT | LBRACKET | COLON
        ;
    
    elementSubsequent
        : HASH
        | cssClass
        | attrib
        | pseudo
        ;
    
    cssClass
        : DOT IDENT
        ;
    
    elementName
        : IDENT
        | STAR
        ;
    
    

    这用于句法谓词。

    语法链接: http://www.antlr.org/grammar/1240941192304/css21.g

        4
  •  0
  •   diyoda_    12 年前

    刚刚通过谷歌来到这里,发现了一个很好的资源,一个真正的实现。对于那些来搜索完整CSS Antlr语法的人来说,请查看 this 语法文件。这可以给你一个想法,或者你可以直接使用它。

    推荐文章