aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrançois Pottier <francois.pottier@inria.fr>2015-10-07 10:49:42 +0200
committerFrançois Pottier <francois.pottier@inria.fr>2015-10-07 10:49:42 +0200
commit09527e66514edcfa20a0341acd75c1fe6fd77363 (patch)
treec0983f011758c1d8cbe3ad748a3f157a89bf6d6d
parentc1937e330a3ca6c19ef648e2dcfe4871fc3c2219 (diff)
downloadcompcert-09527e66514edcfa20a0341acd75c1fe6fd77363.tar.gz
compcert-09527e66514edcfa20a0341acd75c1fe6fd77363.zip
Introduced optional(X, Y), which means X? Y, and used it in array declarators and FOR loops.
This leads to fewer automaton states, and potentially better error messages.
-rw-r--r--cparser/pre_parser.mly16
1 files changed, 12 insertions, 4 deletions
diff --git a/cparser/pre_parser.mly b/cparser/pre_parser.mly
index 497851bf..62a57618 100644
--- a/cparser/pre_parser.mly
+++ b/cparser/pre_parser.mly
@@ -97,6 +97,14 @@ option(X):
| x = X
{ Some x }
+(* [optional(X, Y)] is equivalent to [X? Y]. However, by inlining
+ the two possibilies -- either [X Y] or just [Y] -- we are able
+ to give more meaningful syntax error messages. [optional(X, Y)]
+ itself is usually NOT inlined, as that would cause a useless
+ explosion of cases. *)
+optional(X, Y):
+ ioption(X) Y {}
+
%inline fst(X):
| x = X
{ fst x }
@@ -537,7 +545,7 @@ direct_declarator:
| i = general_identifier
{ set_id_type i VarId; (i, None) }
| LPAREN x = declarator RPAREN
-| x = direct_declarator LBRACK type_qualifier_list? assignment_expression? RBRACK
+| x = direct_declarator LBRACK type_qualifier_list? optional(assignment_expression, RBRACK)
{ x }
| x = direct_declarator LPAREN
open_context parameter_type_list? restore_fun = save_contexts_stk
@@ -583,7 +591,7 @@ abstract_declarator:
direct_abstract_declarator:
| LPAREN abstract_declarator RPAREN
-| option(direct_abstract_declarator) LBRACK type_qualifier_list? assignment_expression? RBRACK
+| option(direct_abstract_declarator) LBRACK type_qualifier_list? optional(assignment_expression, RBRACK)
| ioption(direct_abstract_declarator) LPAREN in_context(parameter_type_list?) RPAREN
{}
@@ -764,8 +772,8 @@ iteration_statement(openc,last_statement):
| WHILE openc LPAREN expression RPAREN last_statement
| DO open_context statement_finish_close WHILE
openc LPAREN expression RPAREN close_context SEMICOLON
-| FOR openc LPAREN expression? SEMICOLON expression? SEMICOLON expression? RPAREN last_statement
-| FOR openc LPAREN declaration expression? SEMICOLON expression? RPAREN last_statement
+| FOR openc LPAREN optional(expression, SEMICOLON) optional(expression, SEMICOLON) optional(expression, RPAREN) last_statement
+| FOR openc LPAREN declaration optional(expression, SEMICOLON) optional(expression, RPAREN) last_statement
{}
asm_attributes: