/* PAS.Y: ISO Level 0 Pascal grammar, adapted to TP Yacc 2-28-89 AG To compile: yacc pas lex paslex tpc pas */ %{ (* * * Pascal grammar in Yacc format, based originally on BNF given * in "Standard Pascal -- User Reference Manual", by Doug Cooper. * This in turn is the BNF given by the ANSI and ISO Pascal standards, * and so, is PUBLIC DOMAIN. The grammar is for ISO Level 0 Pascal. * The grammar has been massaged somewhat to make it LALR, and added * the following extensions. * * constant expressions * otherwise statement in a case * productions to correctly match else's with if's * beginnings of a separate compilation facility * *) uses LexLib, YaccLib; var filename : String; procedure yyerror(msg : string); begin writeln(filename, ': ', yylineno, ': ', msg, ' at or before `', yytext, '''.') end(*yyerror*); %} /* Note the Pascal keyword tokens are stropped with leading underscore (e.g. _AND) in the Turbo Pascal Yacc version, because these identifiers will be declared as token numbers in the output file generated by Yacc, and hence must not collide with Turbo Pascal keywords. */ %token _AND _ARRAY ASSIGNMENT _BEGIN _CASE CHARACTER_STRING COLON COMMA _CONST DIGSEQ %token _DIV _DO DOT DOTDOT _DOWNTO _ELSE _END EQUAL _EXTERNAL _FILE _FOR _FORWARD _FUNCTION %token GE _GOTO GT IDENTIFIER _IF _IN _LABEL LBRAC LE LPAREN LT MINUS _MOD _NIL _NOT %token NOTEQUAL _OF _OR _OTHERWISE _PACKED PLUS _PROCEDURE _PROGRAM RBRAC %token REALNUMBER _RECORD _REPEAT RPAREN SEMICOLON _SET SLASH STAR STARSTAR _THEN %token _TO _TYPE _UNTIL UPARROW _VAR _WHILE _WITH %token ILLEGAL %% file : program | program error { writeln(yylineno, ':Text follows logical end of program.'); } | module ; program : program_heading semicolon block DOT ; program_heading : _PROGRAM identifier | _PROGRAM identifier LPAREN identifier_list RPAREN ; identifier_list : identifier_list comma identifier | identifier ; block : label_declaration_part constant_definition_part type_definition_part variable_declaration_part procedure_and_function_declaration_part statement_part ; module : constant_definition_part type_definition_part variable_declaration_part procedure_and_function_declaration_part ; label_declaration_part : _LABEL label_list semicolon | ; label_list : label_list comma label | label ; label : DIGSEQ ; constant_definition_part : _CONST constant_list | ; constant_list : constant_list constant_definition | constant_definition ; constant_definition : identifier EQUAL cexpression semicolon ; /*constant : cexpression ; /* good stuff! */ cexpression : csimple_expression | csimple_expression relop csimple_expression ; csimple_expression : cterm | csimple_expression addop cterm ; cterm : cfactor | cterm mulop cfactor ; cfactor : sign cfactor | cexponentiation ; cexponentiation : cprimary | cprimary STARSTAR cexponentiation ; cprimary : identifier | LPAREN cexpression RPAREN | unsigned_constant | _NOT cprimary ; constant : non_string | sign non_string | CHARACTER_STRING ; sign : PLUS | MINUS ; non_string : DIGSEQ | identifier | REALNUMBER ; type_definition_part : _TYPE type_definition_list | ; type_definition_list : type_definition_list type_definition | type_definition ; type_definition : identifier EQUAL type_denoter semicolon ; type_denoter : identifier | new_type ; new_type : new_ordinal_type | new_structured_type | new_pointer_type ; new_ordinal_type : enumerated_type | subrange_type ; enumerated_type : LPAREN identifier_list RPAREN ; subrange_type : constant DOTDOT constant ; new_structured_type : structured_type | _PACKED structured_type ; structured_type : array_type | record_type | set_type | file_type ; array_type : _ARRAY LBRAC index_list RBRAC _OF component_type ; index_list : index_list comma index_type | index_type ; index_type : ordinal_type ; ordinal_type : new_ordinal_type | identifier ; component_type : type_denoter ; record_type : _RECORD record_section_list _END | _RECORD record_section_list semicolon variant_part _END | _RECORD variant_part _END ; record_section_list : record_section_list semicolon record_section | record_section ; record_section : identifier_list COLON type_denoter ; variant_part : _CASE variant_selector _OF variant_list semicolon | _CASE variant_selector _OF variant_list | ; variant_selector : tag_field COLON tag_type | tag_type ; variant_list : variant_list semicolon variant | variant ; variant : case_constant_list COLON LPAREN record_section_list RPAREN | case_constant_list COLON LPAREN record_section_list semicolon variant_part RPAREN | case_constant_list COLON LPAREN variant_part RPAREN ; case_constant_list : case_constant_list comma case_constant | case_constant ; case_constant : constant | constant DOTDOT constant ; tag_field : identifier ; tag_type : identifier ; set_type : _SET _OF base_type ; base_type : ordinal_type ; file_type : _FILE _OF component_type ; new_pointer_type : UPARROW domain_type ; domain_type : identifier ; variable_declaration_part : _VAR variable_declaration_list semicolon | ; variable_declaration_list : variable_declaration_list semicolon variable_declaration | variable_declaration ; variable_declaration : identifier_list COLON type_denoter ; procedure_and_function_declaration_part : proc_or_func_declaration_list semicolon | ; proc_or_func_declaration_list : proc_or_func_declaration_list semicolon proc_or_func_declaration | proc_or_func_declaration ; proc_or_func_declaration : procedure_declaration | function_declaration ; procedure_declaration : procedure_heading semicolon directive | procedure_heading semicolon procedure_block ; procedure_heading : procedure_identification | procedure_identification formal_parameter_list ; directive : _FORWARD | _EXTERNAL ; formal_parameter_list : LPAREN formal_parameter_section_list RPAREN ; formal_parameter_section_list : formal_parameter_section_list semicolon formal_parameter_section | formal_parameter_section ; formal_parameter_section : value_parameter_specification | variable_parameter_specification | procedural_parameter_specification | functional_parameter_specification ; value_parameter_specification : identifier_list COLON identifier ; variable_parameter_specification : _VAR identifier_list COLON identifier ; procedural_parameter_specification : procedure_heading ; functional_parameter_specification : function_heading ; procedure_identification : _PROCEDURE identifier ; procedure_block : block ; function_declaration : function_heading semicolon directive | function_identification semicolon function_block | function_heading semicolon function_block ; function_heading : _FUNCTION identifier COLON result_type | _FUNCTION identifier formal_parameter_list COLON result_type ; result_type : identifier ; function_identification : _FUNCTION identifier ; function_block : block ; statement_part : compound_statement ; compound_statement : _BEGIN statement_sequence _END ; statement_sequence : statement_sequence semicolon statement | statement | error { writeln('statement ignored'); yyclearin } ; statement : open_statement | closed_statement ; open_statement : label COLON non_labeled_open_statement | non_labeled_open_statement ; closed_statement : label COLON non_labeled_closed_statement | non_labeled_closed_statement ; non_labeled_closed_statement : assignment_statement | procedure_statement | goto_statement | compound_statement | case_statement | repeat_statement | closed_with_statement | closed_if_statement | closed_while_statement | closed_for_statement | ; non_labeled_open_statement : open_with_statement | open_if_statement | open_while_statement | open_for_statement ; repeat_statement : _REPEAT statement_sequence _UNTIL boolean_expression ; open_while_statement : _WHILE boolean_expression _DO open_statement ; closed_while_statement : _WHILE boolean_expression _DO closed_statement ; open_for_statement : _FOR control_variable ASSIGNMENT initial_value direction final_value _DO open_statement ; closed_for_statement : _FOR control_variable ASSIGNMENT initial_value direction final_value _DO closed_statement ; open_with_statement : _WITH record_variable_list _DO open_statement ; closed_with_statement : _WITH record_variable_list _DO closed_statement ; open_if_statement : _IF boolean_expression _THEN statement | _IF boolean_expression _THEN closed_statement _ELSE open_statement ; closed_if_statement : _IF boolean_expression _THEN closed_statement _ELSE closed_statement ; assignment_statement : variable_access ASSIGNMENT expression ; variable_access : identifier | indexed_variable | field_designator | variable_access UPARROW ; indexed_variable : variable_access LBRAC index_expression_list RBRAC ; index_expression_list : index_expression_list comma index_expression | index_expression ; index_expression : expression ; field_designator : variable_access DOT identifier ; procedure_statement : identifier params | identifier ; params : LPAREN actual_parameter_list RPAREN ; actual_parameter_list : actual_parameter_list comma actual_parameter | actual_parameter ; /* * this forces you to check all this to be sure that only write and * writeln use the 2nd and 3rd forms, you really can't do it easily in * the grammar, especially since write and writeln aren't reserved */ actual_parameter : expression | expression COLON expression | expression COLON expression COLON expression ; goto_statement : _GOTO label ; case_statement : _CASE case_index _OF case_list_element_list _END | _CASE case_index _OF case_list_element_list SEMICOLON _END | _CASE case_index _OF case_list_element_list semicolon otherwisepart statement _END | _CASE case_index _OF case_list_element_list semicolon otherwisepart statement SEMICOLON _END ; case_index : expression ; case_list_element_list : case_list_element_list semicolon case_list_element | case_list_element ; case_list_element : case_constant_list COLON statement ; otherwisepart : _OTHERWISE | _OTHERWISE COLON ; control_variable : identifier ; initial_value : expression ; direction : _TO | _DOWNTO ; final_value : expression ; record_variable_list : record_variable_list comma variable_access | variable_access ; boolean_expression : expression ; expression : simple_expression | simple_expression relop simple_expression | error ; simple_expression : term | simple_expression addop term ; term : factor | term mulop factor ; factor : sign factor | exponentiation ; exponentiation : primary | primary STARSTAR exponentiation ; primary : variable_access | unsigned_constant | function_designator | set_constructor | LPAREN expression RPAREN | _NOT primary ; unsigned_constant : unsigned_number | CHARACTER_STRING | _NIL ; unsigned_number : unsigned_integer | unsigned_real ; unsigned_integer : DIGSEQ ; unsigned_real : REALNUMBER ; /* functions with no params will be handled by plain identifier */ function_designator : identifier params ; set_constructor : LBRAC member_designator_list RBRAC | LBRAC RBRAC ; member_designator_list : member_designator_list comma member_designator | member_designator ; member_designator : member_designator DOTDOT expression | expression ; addop: PLUS | MINUS | _OR ; mulop : STAR | SLASH | _DIV | _MOD | _AND ; relop : EQUAL | NOTEQUAL | LT | GT | LE | GE | _IN ; identifier : IDENTIFIER ; semicolon : SEMICOLON ; comma : COMMA ; %% {$I PASLEX} begin filename := paramStr(1); if filename='' then begin write('input file: '); readln(filename); end; assign(yyinput, filename); reset(yyinput); if yyparse=0 then writeln('successful parse!'); end.