[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
When %dprec and %merge aren't enough...
From: |
Marcel Laverdet |
Subject: |
When %dprec and %merge aren't enough... |
Date: |
Mon, 10 Nov 2008 23:10:19 -0800 |
Hello. I'm writing a parser for ECMAScript (http://www.mozilla.org/js/language/E262-3.pdf
) in Bison right now and I'm having some problems dealing with
ambiguities in the language. The relevant portions of my grammar are
as follows:
statement_list:
source_element
| statement_list source_element
;
source_element:
statement
| function_declaration
;
statement:
block
| expression_statement
| empty_statement
<...>
;
block:
t_LCURLY statement_list t_RCURLY
| t_LCURLY t_RCURLY
;
expression_statement:
expression_statement t_SEMICOLON
;
empty_statement:
t_SEMICOLON
;
expression:
object_literal
<...>
;
object_literal:
t_LCURLY t_RCURLY
| t_LCURLY property_name_and_value_list t_RCURLY
;
Sorry for so much grammar but it's the best way I can convey what's
going on here. Basically ECMAScript implements an ObjectLiteral
expression which is similar to, for instance, a dictionary in Python.
var foo = {};
would create a new empty ObjectLiteral. This syntax can be ambiguous
with Blocks, for example:
if(1){};
It's unclear here whether the child of the if statement should be an
empty Block or an empty ObjectLiteral. The ECMAScript spec addresses
this simply:
"Note that an ExpressionStatement cannot start with an opening curly
brace because that might make it ambiguous with a Block."
Unfortunately there doesn't seem to be any way to express this in
Bison. Additionally it doesn't seem like I can use a %dprec directive
since a Block doesn't reduce the semicolon. Basically it gets a
conflict of
statement -> block -> t_LCURLY t_RCURLY
and
statement -> expression_statement -> object_literal t_SEMICOLON
In the Block case, the leftover semicolon is parsed as an
empty_expression. So I end up with a conflict between either two
statement_list's or a source_element and a statement_list.
So far the only potential way I've discovered to resolve the conflict
is to put a %merge directive on both expansions of statement_list and
manually crawl up my parse tree to figure out which one I should pick.
This solution is extremely cumbersome though and I really want to
think that there's a better way.
Thanks for any help you can provide!
- When %dprec and %merge aren't enough...,
Marcel Laverdet <=