使用ANTLR解析CSS – 边缘情况

前端之家收集整理的这篇文章主要介绍了使用ANTLR解析CSS – 边缘情况前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试使用ANTLR解析CSS,或者至少是基础知识.我的lexer规则遇到了一些问题.问题在于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被标记为COLOR标记,即使它应该是一个选择器.如果我将选择器更改为不以十六进制字符开头,则可以正常工作.我不知道如何解决这个问题.有没有办法让ANTLR将特定标记仅作为COLOR标记处理,如果它在某个位置?比方说,如果它属于属性规则,我可以放心地认为它是一个颜色标记.如果不是,请将其视为选择器.

任何帮助,将不胜感激!

解决方案:原来我试图在语法中做太多,我应该在使用AST的代码中处理. CSS有太多不明确的令牌可靠地分成不同的令牌,所以我现在使用的方法基本上是将特殊字符标记为’#’,’.’,’:’和花括号,并在后面进行后期处理.消费者代码.工作得更好,处理边缘情况更容易.

解决方法

尝试将lexer文件中的#从COLOR移动到它自己的东西,如下:
LLETTERS: ( 'a'..'z' )
ULETTERS: ( 'A'..'Z' )
NUMBERS: ( '0'..'9' )
HASH : '#';

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

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

等等

这允许您以语法方式指定差异,这可以粗略地描述为上下文,而不是词法,大致可以通过外观来描述.如果某些东西的含义根据它的位置而改变,那么应该在语法中指定差异,而不是词法分析器.

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

原文链接:https://www.f2er.com/css/215792.html

猜你在找的CSS相关文章