I started to write long posts not so long time ago, so let me keep this tradition and mention my search for elegant LALR grammar for lists of nested lists.
Let's say we need to parse token stream:
BBABBBABBas the list of two items with one nested list inside. The ideal result would look like
(B (BAB) B) (B (BAB) B).The grammar that comes to mind is:
list: itemThis grammar is ambiguous and has one shift-reduce conflict (it's not clear whether we shall reduce finishing the list or shift starting it). All LALR parser generators would resolve the conflict to shift over reduce and would in fact make our parser fail. So we need to say "prefer reduce". I have several solutions but the cleanest (from the parser's viewpoint) is to add an artificial terminal, say X, denoting the beginning of the list. The grammar
| item list
;
item: B list B
| A
;
list: itemhas no conflicts at all. This solution is good for parser but hacky for lexer which has to supply this fake terminal;) Well, I'm sure there are better solutions but I'm completely missing them today.
| item list
;
item: X B list B
| A
;
Addon: of course, if we allow to modify the lexer, something like
list: itemwould be even better.
| item list
;
item: B_START list B_END
| A
;

No comments:
Post a Comment