# 'stacc' parser for drift .common "drift_com.r.i"; # file containing global variables .symbol Symbol; # "current symbol" variable .scanner getsym; # name of lexical analysis routine .state state; # "parse state" variable .terminal # terminal symbols 256 # start higher than largest character value FLOAT_SYM ID_SYM FUNCTION_SYM END_FUNCTION_SYM NULL_SYM NUMBER_SYM WHILE_SYM DO_SYM OD_SYM IF_SYM THEN_SYM ELSE_SYM FI_SYM ; .ext_term # terminal symbols defined elsewhere NEWLINE EOF ; program -> ! call begin_program nls { declaration nls } EOF. ! call end_program ? call pmr ("EOF expected*n"p, state) ; declaration -> global_variable_declaration | function_declaration ; global_variable_declaration -> FLOAT_SYM ID_SYM ! call declare_global_variable (Symtext) ? call pmr ("missing identifier*n"p, state, state) { ',' nls ID_SYM ! call declare_global_variable (Symtext) ? call pmr ("missing identifier*n"p, state) } ; nls -> { NEWLINE } ; function_declaration -> FUNCTION_SYM ID_SYM ! call begin_function (Symtext) ? call pmr ("missing function name*n"p, state) '(' ! call make_null ? call pmr ("missing parameters*n"p, state) formal_parameters ! call make_function_parameters ')' ? call pmr ("missing ')'*n"p, state) nls ! call make_null { local_variable_declaration nls } series ! call make_function_body ? call pmr ("missing function body*n"p, state) nls END_FUNCTION_SYM ! call end_function ? call pmr ("missing 'end_function'*n"p, state) ; formal_parameters -> ID_SYM ! call declare_formal_parameter (Symtext) { ',' nls ID_SYM ! call declare_formal_parameter (Symtext) ? call pmr ("missing identifier*n"p, state) } | epsilon ; local_variable_declaration -> FLOAT_SYM ID_SYM ! call declare_local_variable (Symtext) ? call pmr ("missing identifier*n"p, state) { ',' nls ID_SYM ! call declare_local_variable (Symtext) ? call pmr ("missing identifier*n"p, state) } ; series -> expression nls { expression ! call sequentialize nls } ; expression -> sum { '=' sum ! call make_dyad (ASSIGN_NODE) ? call pmr ("missing right-hand-side*n"p, state) } ; sum -> ! integer node term { ( '+' ! node = ADD_NODE | '-' ! node = SUBTRACT_NODE ) term ! call make_dyad (node) ? call pmr ("missing right operand*n"p, state) } ; term -> ! integer node primary { ( '*' ! node = MULTIPLY_NODE | '/' ! node = DIVIDE_NODE ) primary ! call make_dyad (node) ? call pmr ("missing right operand*n"p, state) } ; primary -> ! character id (MAX_SYM_LEN) '#' ! call make_quad | NULL_SYM ! call make_null | NUMBER_SYM ! call make_constant (Symval) | ID_SYM ! call scopy (Symtext, 1, id, 1) ( '(' actual_parameters ')' ! call make_call (id) ? call pmr ("missing ')'*n"p, state) | epsilon ! call make_object (id) ) | loop | conditional | '(' series ')' ? call pmr ("missing ')'*n"p, state) ; loop -> WHILE_SYM nls series ? call pmr ("missing loop condition*n"p, state) nls DO_SYM ? call pmr ("missing 'do'*n"p, state) nls series ? call pmr ("missing loop body*n"p, state) nls OD_SYM ! call make_loop ? call pmr ("missing 'od'*n"p, state) ; conditional -> IF_SYM nls series ? call pmr ("missing 'if' condition*n"p, state) nls THEN_SYM ? call pmr ("missing 'then'*n"p, state) nls series ? call pmr ("missing then_part*n"p, state) ( ELSE_SYM nls series ? call pmr ("missing else_part*n"p, state) nls | nls ! call make_null ) FI_SYM ! call make_conditional ? call pmr ("missing 'fi'*n"p, state) ; actual_parameters -> ! call make_null series ! call make_actual_parameter { ',' nls series ! call make_actual_parameter ? call pmr ("missing parameter after ','*n"p, state) } | epsilon ;