I'm trying to parse CSS, or at least the basics, using ANTLR. I'm running into a few problems with my lexer rules though. The problem lies in the ambiguity between an ID selectors and hexadecimal color values. Using a simplified grammar for clarity, consider the following input:
#bbb {
color: #fff;
}
and the following parser rules:
ruleset : selector '{' property* '}';
selector: '#' ALPHANUM;
property: ALPHANUM ':' value ';' ;
value: COLOR;
and these lexer tokens:
ALPHANUM : ('a'..'z' | '0'..'9')+;
COLOR : '#' ('0'..'9' | 'a'..'f')+;
This will not work, because #bbb is tokenized as a COLOR token, even though it's supposed to be a selector. If I change the selector to not start with a hexadecimal character, it works fine. I'm not sure how to solve this. Is there a way to tell ANTLR to treat a specific token only as a COLOR token if it's in a certain position? Say, if it's in a property rule, I can safely assume it's a color token. If it isn't, treat it as a selector.
Any help would be appreciated!
Solution: Turns out I was trying to do too much in the grammar, which I should probably deal with in the code using the AST. CSS has too many ambiguous tokens to reliably split into different tokens, so the approach I'm using now is basically tokenizing the special characters like '#', '.', ':' and the curly braces, and doing post processing in the consumer code. Works a lot better, and it's easier to deal with the edge cases.