9

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

#bbb {
  color: #fff;
}

以及以下解析器规则:

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

和这些词法分析器标记:

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

这不起作用,因为#bbb 被标记为颜色标记,即使它应该是一个选择器。如果我将选择器更改为不以十六进制字符开头,它可以正常工作。我不知道如何解决这个问题。有没有办法告诉 ANTLR 仅将特定标记视为颜色标记(如果它位于某个位置)?比如说,如果它在属性规则中,我可以安全地假设它是一个颜色标记。如果不是,则将其视为选择器。

任何帮助,将不胜感激!


解决方案:原来我试图在语法中做太多事情,我可能应该在使用 AST 的代码中处理。CSS 有太多模棱两可的标记,无法可靠地拆分成不同的标记,所以我现在使用的方法基本上是标记特殊字符,如'#'、'.'、':' 和花括号,并在消费者代码。效果更好,并且更容易处理边缘情况。

4

4 回答 4

8

尝试将 lexer 文件中的 # 从 COLOR 移动到它自己的东西,如下所示:

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

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

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

等等

这允许您在语法上指定差异,可以粗略地描述为上下文,而词汇上,可以粗略地描述为外观。如果某事物的含义根据其所在位置而变化,则应在语法中而不是词法分析器中指定该差异。

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

于 2009-08-24T23:32:47.323 回答
2

同 Walt 所说的一样,附录 G. CSS 2.1 语法对 lex 说HASH,然后(取决于它相对于其他标记的位置)将 a 解析HASH为 asimple_selector或 a hexcolor

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

"#"{name}       {return HASH;}

...并且语法包括以下规则...

hexcolor
  : HASH S*
  ;

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

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

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

于 2009-08-24T23:40:15.920 回答
0

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

  • 句法谓词
  • 语义谓词

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

简单选择器
    : 元素名称
        ((esPred)=>elementSubsequent)*

    | ((esPred)=>elementSubsequent)+
    ;

esPred
    : 哈希 | 点 | 左支架 | 冒号
    ;

元素后续
    : 哈希
    | css类
    | 属性
    | 伪
    ;

css类
    : 点标识
    ;

元素名称
    : 标识
    | 星星
    ;

这用于语法谓词。

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

于 2012-07-09T22:32:36.830 回答
0

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

于 2013-07-10T17:47:09.420 回答