/* ambiguous-dylan-phrases.y -- Dylan phrase grammar (naive transliteration) */ /* * Paul Haahr * 19 June 1996 * * This grammar was produced by applying obvious transformations * to the phrase grammar from Appendix A: BNF (pages 414-424) of * the Dylan Reference Manual. As much as possible, I left the * grammar alone, which meant that there are ambiguities remaining. * (I believe there should be 36 shift/reduce conflicts, and no * reduce/reduce conflicts.) * * I tried to strike a reasonable balance between the parser and the * tokenizer. The notable area where I shifted some responsibility * from the lexical grammar into the phrase grammar is in the * categorization of word and name tokens; I don't know any other way * to do this. * * In practice, aside from dealing with the ambiguities already present, * one must split the word categorizations to allow use of defining words * as unreserved names. * * This YACC program is in the public domain. */ /* names and related tokens */ %token UNRESERVED_WORD %token BEGIN_WORD %token FUNCTION_WORD %token DEFINE_BODY_WORD %token DEFINE_LIST_WORD %token BINARY_OPERATOR %token UNARY_OPERATOR %token ESCAPED_WORD /* \word */ %token OPERATOR_NAME /* \operator */ %token CONSTRAINED_NAME /* core words */ %token DEFINE %token END %token HANDLER %token LET %token LOCAL %token MACRO %token OTHERWISE %token METHOD /* not quite reserved */ /* literals */ %token SYMBOL %token NUMBER %token CHARACTER_LITERAL %token STRING /* punctuation */ %token '(' ')' %token ',' %token '.' %token ';' %token '[' ']' %token '{' '}' %token COLON_COLON /* "::" */ %token '-' %token '=' %token EQUAL_EQUAL /* "==" */ %token EQUAL_ARROW /* "=>" */ %token HASH_PAREN /* "#(" */ %token HASH_BRACKET /* "#[" */ %token HASH_HASH /* "##" */ %token '?' %token QUERY_QUERY /* "??" */ %token QUERY_EQUAL /* "?=" */ %token ELLIPSIS /* "..." */ /* hash words */ %token HASH_T %token HASH_F %token HASH_NEXT %token HASH_REST %token HASH_KEY %token HASH_ALL_KEYS %token HASH_INCLUDE /* parsed fragments, from page 424 */ %token PARSED_DEFINITION %token PARSED_LOCAL_DECLARATION %token PARSED_FUNCTION_CALL %token PARSED_MACRO_CALL %token PARSED_LIST_CONSTANT %token PARSED_VECTOR_CONSTANT /* entry points */ %start start %token ENTRY_SOURCE_RECORD /* main entry point */ %token ENTRY_EXPRESSION /* pattern variable constraint :expression */ %token ENTRY_VARIABLE /* pattern variable constraint :variable */ %token ENTRY_NAME /* pattern variable constraint :name */ %token ENTRY_TOKEN /* pattern variable constraint :token */ %token ENTRY_BODY /* pattern variable constraint :body */ %token ENTRY_CASE_BODY /* pattern variable constraint :case-body */ %token ENTRY_MACRO /* pattern variable constraint :macro */ %token STOP /* end of current token stream */ %% /* parsing entry points */ /* * The Dylan grammar can be entered at several places, based on * how it is invoked. The top level entry point parses source * records, which are the units of programs. Each of the pattern * variable constraints (other than :*, for wildcards) can * needs to do test parsing on a token stream, so each requires * its own parser entry. (That's not entirely true, as some are * so simple that there's no need to really start up the parser * for :name or :token, and :body is no different inside the * parser for dealing with source records, but the easiest thing * to do for the grammar was provide all the entry points, and * leave up to a client of this grammar to choose which ones to * use in practice.) * * The STOP token is used to provide a portable way of indicating * that a token stream is over. STOP for source records should be * communicated based on the development environment, whereas STOP * for body or case-body comes from intermediate word detection. * * The pattern variable constraints and what syntax they accept * are listed on pages 157-158. */ start : ENTRY_SOURCE_RECORD source_record STOP | ENTRY_VARIABLE variable STOP | ENTRY_EXPRESSION expression STOP | ENTRY_NAME name STOP | ENTRY_TOKEN token STOP | ENTRY_BODY body_opt STOP | ENTRY_CASE_BODY case_body_opt STOP | ENTRY_MACRO macro STOP /* Program Structure, page 414 */ source_record : body_opt body : constituents semicolon_opt constituents : constituent | constituents ';' constituent constituent : definition | local_declaration | expression macro : definition_macro_call | statement | function_macro_call | PARSED_MACRO_CALL /* Property Lists, page 414 */ comma_property_list : ',' property_list property_list : property | property_list ',' property property : SYMBOL value value : basic_fragment /* Fragments, pages 415-416 */ body_fragment : non_statement_body_fragment | statement non_statement_body_fragment_opt list_fragment : non_statement_list_fragment | statement non_statement_list_fragment_opt basic_fragment : non_statement_basic_fragment | statement non_statement_basic_fragment_opt non_statement_body_fragment : definition semicolon_fragment_opt | local_declaration semicolon_fragment_opt | simple_fragment body_fragment_opt | ',' body_fragment_opt | ';' body_fragment_opt semicolon_fragment : ';' body_fragment_opt non_statement_list_fragment : simple_fragment list_fragment_opt | ',' list_fragment_opt non_statement_basic_fragment : simple_fragment basic_fragment_opt simple_fragment : variable_name | constant_fragment | BINARY_OPERATOR | UNARY_OPERATOR | bracketed_fragment | function_macro_call | hash_word | '.' | COLON_COLON | EQUAL_ARROW | '?' | QUERY_QUERY | QUERY_EQUAL | ELLIPSIS | HASH_HASH | OTHERWISE | PARSED_FUNCTION_CALL | PARSED_MACRO_CALL bracketed_fragment : '(' body_fragment_opt ')' | '[' body_fragment_opt ']' | '{' body_fragment_opt '}' constant_fragment : NUMBER | CHARACTER_LITERAL | STRING | SYMBOL | HASH_PAREN constants '.' constant ')' | HASH_PAREN constants_opt ')' | HASH_BRACKET constants_opt ']' | PARSED_LIST_CONSTANT | PARSED_VECTOR_CONSTANT /* Definitions, page 416 */ definition : definition_macro_call | DEFINE MACRO macro_definition | PARSED_DEFINITION definition_macro_call : DEFINE modifiers_opt DEFINE_BODY_WORD body_fragment_opt definition_tail | DEFINE modifiers_opt DEFINE_LIST_WORD list_fragment_opt modifier : unreserved_name modifiers : modifier | modifiers modifier definition_tail : END | END macro_name | END DEFINE_BODY_WORD macro_name /* Local Declarations, page 417 */ local_declaration : LET bindings | LET HANDLER condition '=' handler | LOCAL local_methods | PARSED_LOCAL_DECLARATION condition : type | '(' type comma_property_list ')' handler : expression local_methods : METHOD_opt method_definition | local_methods ',' METHOD_opt method_definition bindings : variable '=' expression | '(' variable_list ')' '=' expression variable_list : variables | variables ',' HASH_REST variable_name | HASH_REST variable_name variables : variable | variables ',' variable variable : variable_name | variable_name COLON_COLON type variable_name : ordinary_name type : operand /* Expression, page 418-419 */ expressions : expression | expressions ',' expression expression : binary_operand | expression BINARY_OPERATOR binary_operand expression_no_symbol : binary_operand_no_symbol | binary_operand_no_symbol BINARY_OPERATOR binary_operand binary_operand_no_symbol : UNARY_OPERATOR_opt operand binary_operand : SYMBOL | UNARY_OPERATOR_opt operand operand : operand '(' arguments_opt ')' | operand '[' arguments_opt ']' | operand '.' variable_name | leaf function_macro_call : FUNCTION_WORD '(' body_fragment_opt ')' leaf : literal | variable_name | '(' expression ')' | function_macro_call | statement | PARSED_FUNCTION_CALL | PARSED_MACRO_CALL arguments : argument | arguments ',' argument argument : SYMBOL expression | expression_no_symbol | SYMBOL literal : NUMBER | CHARACTER_LITERAL | string_literal | HASH_T | HASH_F | HASH_PAREN constants '.' constant ')' | HASH_PAREN constants_opt ')' | HASH_BRACKET constants_opt ']' | PARSED_LIST_CONSTANT | PARSED_VECTOR_CONSTANT string_literal : STRING | string_literal STRING constants : constant | constants ',' constant constant : literal | SYMBOL /* Statements, page 419 */ statement : BEGIN_WORD body_fragment_opt end_clause end_clause : END BEGIN_WORD_opt case_body : cases semicolon_opt cases : case_label constituents_opt | cases ';' case_label constituents_opt case_label : expressions EQUAL_ARROW | '(' expression ',' expressions ')' EQUAL_ARROW | OTHERWISE EQUAL_ARROW_opt /* Methods, pages 420-421 */ method_definition : variable_name parameter_list body_opt END METHOD_opt variable_name_opt parameter_list : '(' parameters_opt ')' semicolon_opt | '(' parameters_opt ')' EQUAL_ARROW variable ';' | '(' parameters_opt ')' EQUAL_ARROW '(' values_list_opt ')' semicolon_opt parameters : required_parameters | required_parameters ',' next_rest_key_parameter_list | next_rest_key_parameter_list next_rest_key_parameter_list : HASH_NEXT variable_name | HASH_NEXT variable_name ',' rest_key_parameter_list | rest_key_parameter_list rest_key_parameter_list : HASH_REST variable_name | HASH_REST variable_name ',' key_parameter_list | key_parameter_list key_parameter_list : HASH_KEY keyword_parameters_opt | HASH_KEY keyword_parameters_opt ',' HASH_ALL_KEYS required_parameters : required_parameter | required_parameters ',' required_parameter required_parameter : variable | variable_name EQUAL_EQUAL expression keyword_parameters : keyword_parameter | keyword_parameters ',' keyword_parameter keyword_parameter : SYMBOL_opt variable default_opt default : '=' expression values_list : variables | variables ',' HASH_REST variable | HASH_REST variable /* Macro Definitions, page 421 */ macro_definition : macro_name main_rule_set aux_rule_sets_opt END MACRO_opt macro_name_opt main_rule_set : body_style_definition_rules | list_style_definition_rules | statement_rules | function_rules body_style_definition_rules : body_style_definition_rule | body_style_definition_rules body_style_definition_rule list_style_definition_rules : list_style_definition_rule | list_style_definition_rules list_style_definition_rule statement_rules : statement_rule | statement_rules statement_rule function_rules : function_rule | function_rules function_rule body_style_definition_rule : '{' DEFINE definition_head_opt macro_name pattern_opt semicolon_opt END '}' EQUAL_ARROW rhs list_style_definition_rule : '{' DEFINE definition_head_opt macro_name pattern_opt '}' EQUAL_ARROW rhs rhs : '{' template_opt '}' semicolon_opt definition_head : modifier_pattern | definition_head modifier_pattern modifier_pattern : modifier | pattern_variable statement_rule : '{' macro_name pattern_opt semicolon_opt END '}' EQUAL_ARROW rhs function_rule : '{' macro_name '(' pattern_opt ')' '}' EQUAL_ARROW rhs /* Patterns, pages 421-423 */ pattern : pattern_list | pattern ';' pattern_list pattern_list : pattern_sequence | pattern_sequence ',' pattern_list | property_list_pattern pattern_sequence : simple_pattern | pattern_sequence simple_pattern simple_pattern : name_not_end | EQUAL_ARROW | bracketed_pattern | binding_pattern | pattern_variable bracketed_pattern : '(' pattern_opt ')' | '[' pattern_opt ']' | '{' pattern_opt '}' binding_pattern : pattern_variable COLON_COLON pattern_variable | pattern_variable '=' pattern_variable | pattern_variable COLON_COLON pattern_variable '=' pattern_variable pattern_variable : '?' name | '?' CONSTRAINED_NAME | ELLIPSIS property_list_pattern : HASH_REST pattern_variable | HASH_KEY pattern_keywords_opt | HASH_REST pattern_variable ',' HASH_KEY pattern_keywords_opt pattern_keywords : HASH_ALL_KEYS | pattern_keyword | pattern_keyword ',' pattern_keywords pattern_keyword : '?' name default_opt | '?' CONSTRAINED_NAME default_opt | QUERY_QUERY name default_opt | QUERY_QUERY CONSTRAINED_NAME default_opt /* Templates, pages 423-424 */ template : template_element | template template_element template_element : name | SYMBOL | NUMBER | CHARACTER_LITERAL | STRING | UNARY_OPERATOR | separator | hash_word | '.' | COLON_COLON | EQUAL_ARROW | '(' template_opt ')' | '[' template_opt ']' | '{' template_opt '}' | HASH_PAREN template_opt ')' | HASH_BRACKET template_opt ']' | PARSED_LIST_CONSTANT | PARSED_VECTOR_CONSTANT | substitution separator : ';' | ',' | BINARY_OPERATOR substitution : name_prefix_opt '?' name_string_or_symbol name_suffix_opt | QUERY_QUERY name separator_opt ELLIPSIS | ELLIPSIS | QUERY_EQUAL name name_prefix : STRING HASH_HASH name_suffix : HASH_HASH STRING name_string_or_symbol : name | STRING | SYMBOL /* Auxiliary Rule Sets, page 424 */ aux_rule_sets : aux_rule_set | aux_rule_sets aux_rule_set aux_rule_set : SYMBOL aux_rules aux_rules : aux_rule | aux_rules aux_rule aux_rule : '{' pattern_opt '}' EQUAL_ARROW rhs /* imports from lexical grammar, pages 408-413 */ token : name | SYMBOL | NUMBER | CHARACTER_LITERAL | STRING | UNARY_OPERATOR | BINARY_OPERATOR | punctuation | hash_word punctuation : bracketing_punctuation | non_bracketing_punctuation bracketing_punctuation : '(' | ')' | '[' | ']' | '{' | '}' | HASH_PAREN | HASH_BRACKET non_bracketing_punctuation : ',' | '.' | ';' | COLON_COLON | '-' | '=' | EQUAL_EQUAL | EQUAL_ARROW | HASH_HASH | '?' | QUERY_QUERY | QUERY_EQUAL | ELLIPSIS reserved_word : core_word | BEGIN_WORD | FUNCTION_WORD | DEFINE_BODY_WORD | DEFINE_LIST_WORD hash_word : HASH_T | HASH_F | HASH_NEXT | HASH_REST | HASH_KEY | HASH_ALL_KEYS | HASH_INCLUDE core_word : non_end_core_word | END non_end_core_word : DEFINE | HANDLER | LET | LOCAL | MACRO | OTHERWISE name : reserved_word | unreserved_name unreserved_name : UNRESERVED_WORD | ESCAPED_WORD | OPERATOR_NAME ordinary_name : unreserved_name | DEFINE_BODY_WORD | DEFINE_LIST_WORD macro_name : ordinary_name | BEGIN_WORD | FUNCTION_WORD name_not_end : macro_name | non_end_core_word /* optional items -- YACC should be able to handle this automatically */ BEGIN_WORD_opt : | BEGIN_WORD EQUAL_ARROW_opt : | EQUAL_ARROW MACRO_opt : | MACRO macro_name_opt : | macro_name METHOD_opt : | METHOD SYMBOL_opt : | SYMBOL UNARY_OPERATOR_opt : | UNARY_OPERATOR arguments_opt : | arguments aux_rule_sets_opt : | aux_rule_sets basic_fragment_opt : | basic_fragment body_opt : | body body_fragment_opt : | body_fragment case_body_opt : | case_body constants_opt : | constants constituents_opt : | constituents default_opt : | default definition_head_opt : | definition_head keyword_parameters_opt : | keyword_parameters list_fragment_opt : | list_fragment modifiers_opt : | modifiers name_prefix_opt : | name_prefix name_suffix_opt : | name_suffix non_statement_basic_fragment_opt : | non_statement_basic_fragment non_statement_body_fragment_opt : | non_statement_body_fragment non_statement_list_fragment_opt : | non_statement_list_fragment parameters_opt : | parameters pattern_opt : | pattern pattern_keywords_opt : | pattern_keywords semicolon_opt : | ';' semicolon_fragment_opt : | semicolon_fragment separator_opt : | separator template_opt : | template values_list_opt : | values_list variable_name_opt : | variable_name