From 30ac183455a0e15fb9889793a3bc774bc1b7b5c2 Mon Sep 17 00:00:00 2001 From: François Pottier Date: Wed, 7 Oct 2015 09:56:12 +0200 Subject: Use [option] as much as possible and [ioption] only where necessary. The existing [option(X)] was marked %inline, and has been renamed [ioption(X)]. A new [option(X)], which is not marked %inline, has been introduced. The grammar now uses [option] everywhere, except where [ioption] is necessary in order to avoid conflicts. This reduces the number of states in the automaton. The number of LR(0) cores drops from 857 to 712. --- cparser/pre_parser.mly | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) (limited to 'cparser/pre_parser.mly') diff --git a/cparser/pre_parser.mly b/cparser/pre_parser.mly index 54322888..14bf4a23 100644 --- a/cparser/pre_parser.mly +++ b/cparser/pre_parser.mly @@ -74,7 +74,24 @@ (* Helpers *) -%inline option(X): +(* Note that, by convention, [X?] is syntactic sugar for [option(X)], + so this definition of [option] is actually used, even though the + word [option] does not appear in the rest of this file. *) + +option(X): +| /* nothing */ + { None } +| x = X + { Some x } + +(* [ioption(X)] is equivalent to [option(X)], but is marked [%inline], + so its definition is expanded. In the absence of conflicts, the two + are equivalent. Using [ioption] instead of [option] in well-chosen + places can help avoid conflicts. Conversely, using [option] instead + of [ioption] in well-chosen places can help reduce the number of + states of the automaton. *) + +%inline ioption(X): | /* nothing */ { None } | x = X @@ -353,20 +370,20 @@ declaration_specifiers_no_typedef_name: The first field is a named t, while the second is unnamed of type t. *) declaration_specifiers: -| declaration_specifiers_no_type? i = TYPEDEF_NAME declaration_specifiers_no_type? +| ioption(declaration_specifiers_no_type) i = TYPEDEF_NAME declaration_specifiers_no_type? { set_id_type i TypedefId } -| declaration_specifiers_no_type? type_specifier_no_typedef_name declaration_specifiers_no_typedef_name? +| ioption(declaration_specifiers_no_type) type_specifier_no_typedef_name declaration_specifiers_no_typedef_name? {} (* This matches declaration_specifiers that do contains once the "typedef" keyword. To avoid conflicts, we also encode the constraint described in the comment for [declaration_specifiers]. *) declaration_specifiers_typedef: -| declaration_specifiers_no_type? TYPEDEF declaration_specifiers_no_type? i = TYPEDEF_NAME declaration_specifiers_no_type? -| declaration_specifiers_no_type? i = TYPEDEF_NAME declaration_specifiers_no_type? TYPEDEF declaration_specifiers_no_type? +| ioption(declaration_specifiers_no_type) TYPEDEF declaration_specifiers_no_type? i = TYPEDEF_NAME declaration_specifiers_no_type? +| ioption(declaration_specifiers_no_type) i = TYPEDEF_NAME declaration_specifiers_no_type? TYPEDEF declaration_specifiers_no_type? { set_id_type i TypedefId } -| declaration_specifiers_no_type? TYPEDEF declaration_specifiers_no_type? type_specifier_no_typedef_name declaration_specifiers_no_typedef_name? -| declaration_specifiers_no_type? type_specifier_no_typedef_name declaration_specifiers_no_typedef_name? TYPEDEF declaration_specifiers_no_typedef_name? +| ioption(declaration_specifiers_no_type) TYPEDEF declaration_specifiers_no_type? type_specifier_no_typedef_name declaration_specifiers_no_typedef_name? +| ioption(declaration_specifiers_no_type) type_specifier_no_typedef_name declaration_specifiers_no_typedef_name? TYPEDEF declaration_specifiers_no_typedef_name? {} (* A type specifier which is not a typedef name. *) @@ -511,7 +528,7 @@ function_specifier: has to be restored if entering the body of the function being defined, if so. *) declarator: -| pointer? x = direct_declarator attribute_specifier_list +| ioption(pointer) x = direct_declarator attribute_specifier_list { x } direct_declarator: @@ -559,13 +576,13 @@ type_name: abstract_declarator: | pointer -| pointer? direct_abstract_declarator +| ioption(pointer) direct_abstract_declarator {} direct_abstract_declarator: | LPAREN abstract_declarator RPAREN -| direct_abstract_declarator? LBRACK type_qualifier_list? assignment_expression? RBRACK -| direct_abstract_declarator? LPAREN in_context(parameter_type_list?) RPAREN +| ioption(direct_abstract_declarator) LBRACK type_qualifier_list? assignment_expression? RBRACK +| ioption(direct_abstract_declarator) LPAREN in_context(parameter_type_list?) RPAREN {} c_initializer: @@ -809,12 +826,12 @@ external_declaration: {} function_definition_begin: -| declaration_specifiers pointer? x=direct_declarator +| declaration_specifiers ioption(pointer) x=direct_declarator { match x with | (_, None) -> $syntaxerror | (i, Some restore_fun) -> restore_fun () } -| declaration_specifiers pointer? x=direct_declarator +| declaration_specifiers ioption(pointer) x=direct_declarator LPAREN params=identifier_list RPAREN open_context declaration_list { match x with | (_, Some _) -> $syntaxerror -- cgit