BEGIN INT tk_COLON = ABS ':'; INT tk_LESS = ABS '<'; INT tk_GREATER = ABS '>'; INT tk_DIV = ABS '/'; INT tk_EQUAL = ABS '='; INT tk_MULT = ABS '*'; INT tk_PLUS = ABS '+'; INT tk_MINUS = ABS '-'; INT tk_PIPE = ABS '|'; INT tk_LBRACKET = ABS '['; INT tk_RBRACKET = ABS ']'; INT tk_LPARENTH = ABS '('; INT tk_RPARENTH = ABS ')'; INT tk_SEMICOLON = ABS ';'; INT tk_COMMA = ABS ','; INT tk_REF = 257; INT tk_LOC = 258; INT tk_STRUCT = 259; INT tk_UNION = 260; INT tk_TRUE = 261; INT tk_FALSE = 262; INT tk_NIL = 263; INT tk_CHARCONST = 264; INT tk_POWER = 265; INT tk_UPB = 266; INT tk_LWB = 267; INT tk_BEGIN = 268; INT tk_END = 269; INT tk_IF = 270; INT tk_THEN = 271; INT tk_ELSE = 272; INT tk_ELIF = 273; INT tk_FI = 274; INT tk_FOR = 275; INT tk_FROM = 276; INT tk_BY = 277; INT tk_TO = 278; INT tk_WHILE = 279; INT tk_DO = 280; INT tk_OD = 281; INT tk_REPR = 282; INT tk_FORWARD = 283; INT tk_MOD = 284; INT tk_ESAC = 285; INT tk_PROC = 286; INT tk_ID = 287; INT tk_INTCONST = 288; INT tk_STRCONST = 289; INT tk_COMMENT = 290; INT tk_MODE = 291; INT tk_AMODE = 292; INT tk_ASSIGN = 293; INT tk_OR = 294; INT tk_OR = 295; INT tk_AND = 296; INT tk_AND = 297; INT tk_NOT = 298; INT tk_ABS = 299; INT tk_NEQ = 300; INT tk_GEQ = 301; INT tk_LEQ = 302; INT tk_IS = 303; INT tk_ISNT = 304; INT tk_OF = 305; INT tk_EOF = 0; INT tk_ERROR = 1001; # General constants INT string_size = 128; # (upper bound - 4, size in octets - 4) INT array_header_size = 8; INT struc_header_size = 8; # New modes & structures MODE TOKEN = STRUCT(INT id, STRING str, STRING descr, INT line, BOOL used); # Variables STRUCT(INT id, STRING str, STRING descr, INT line, BOOL used) token; CHAR nextChar := REPR 0; INT line := 1; BOOL debug_echo := FALSE; BOOL debug_stop := FALSE; BOOL debug_stepwise := FALSE; BOOL debug_expr := FALSE; # Dummy debugger! PROC debugger = VOID: BEGIN 1; END; # Error: on error display message and terminate! PROC error = (STRING msg) VOID: BEGIN printf("ERROR: at token '%s', %s(%i): %s\n", str OF token, descr OF token, id OF token, msg); close(2); close(1); exit; END; PROC read = CHAR: BEGIN CHAR ch := readc(1); # IF (ch = 10) THEN line := line + 1 FI; ch END; PROC IsDigit = (STRING s) BOOL: BEGIN s[0] = '-' OR (s[0] >= '0' AND s[0] <= '9') END; PROC StrLen = (STRING s) INT: BEGIN INT i := 0; WHILE (s[i] /= REPR 0) DO i := i + 1 OD; i END; PROC StrUCase = (STRING s) BOOL: BEGIN INT i := 0; WHILE i < string_size AND s[i] /= REPR 0 AND s[i] >= 'A' AND s[i] <= 'Z' DO i := i + 1 OD; s[i] = REPR 0 END; PROC StrFind = (STRING s, CHAR ch, INT start) INT: BEGIN INT i := start; WHILE i < string_size AND s[i] /= REPR 0 AND s[i] /= ch DO i := i + 1; OD; i END; PROC StrTail = (REF STRING s1, STRING s2, INT pos) VOID: BEGIN INT i := 0; WHILE i+pos < string_size AND s2[i+pos] /= REPR 0 DO s1[i] := s2[i+pos]; i := i + 1 OD; s1[i] := s2[i+pos]; END; PROC StrSlice = (REF STRING t, STRING s, INT start, INT end) VOID: BEGIN INT k := start; WHILE k < string_size AND k <= end DO t[k-start] := s[k]; k := k + 1 OD; t[k-start] := REPR 0; END; PROC StrAppend = (REF STRING s, STRING s1, STRING s2) VOID: BEGIN STRING t; INT i := 0, j := 0; WHILE i < string_size AND s1[i] /= REPR 0 DO t[j] := s1[i]; i := i + 1; j := j + 1 OD; i := 0; WHILE i < string_size AND s2[i] /= REPR 0 DO t[j] := s2[i]; i := i + 1; j := j + 1 OD; t[j] := REPR 0; s := t; END; PROC store_token = (INT id, STRING descr) VOID: BEGIN id OF token := id; descr OF token := descr; line OF token := line; END; PROC GetTokenId = VOID: BEGIN STRING s := str OF token; descr OF token := "RESERVED"; id OF token := IF s = "REF" THEN tk_REF ELIF s = "LOC" THEN tk_LOC ELIF s = "STRUCT" THEN tk_STRUCT ELIF s = "TRUE" THEN tk_TRUE ELIF s = "FALSE" THEN tk_FALSE ELIF s = "NIL" THEN tk_NIL ELIF s = "ABS" THEN tk_ABS ELIF s = "NOT" THEN tk_NOT ELIF s = "AND" THEN tk_AND ELIF s = "OR" THEN tk_OR ELIF s = "AND" THEN tk_AND ELIF s = "OR" THEN tk_OR ELIF s = "IS" THEN tk_IS ELIF s = "ISNT" THEN tk_ISNT ELIF s = "OF" THEN tk_OF ELIF s = "BEGIN" THEN tk_BEGIN ELIF s = "END" THEN tk_END ELIF s = "IF" THEN tk_IF ELIF s = "THEN" THEN tk_THEN ELIF s = "ELSE" THEN tk_ELSE ELIF s = "ELIF" THEN tk_ELIF ELIF s = "FI" THEN tk_FI ELIF s = "FOR" THEN tk_FOR ELIF s = "FROM" THEN tk_FROM ELIF s = "BY" THEN tk_BY ELIF s = "TO" THEN tk_TO ELIF s = "WHILE" THEN tk_WHILE ELIF s = "DO" THEN tk_DO ELIF s = "OD" THEN tk_OD ELIF s = "PROC" THEN tk_PROC ELIF s = "MODE" THEN tk_MODE ELIF s = "LWB" THEN tk_LWB ELIF s = "UPB" THEN tk_UPB ELIF s = "REPR" THEN tk_REPR ELIF s = "FORWARD" THEN tk_FORWARD ELIF s = "MOD" THEN tk_MOD ELIF StrUCase(s) THEN descr OF token := "AMODE"; tk_AMODE ELSE descr OF token := "IDENTIFIER"; tk_ID FI; END; PROC IsSeparator = (CHAR ch) BOOL: BEGIN BOOL result; IF (ch = '(') OR (ch = ')') OR (ch = '[') OR (ch = ']') OR (ch = ':') OR (ch = ';') OR (ch = ',') OR (ch = '*') OR (ch = '+') OR (ch = '-') OR (ch = '=') OR (ch = '/') OR (ch = '>') OR (ch = '<') OR (ch = '|') THEN result := TRUE ELSE result := FALSE FI; result END; PROC IsBlank = (CHAR ch) BOOL: BEGIN # IF ch <= ' ' AND ch /= _eof THEN ch <= ' ' AND ch /= REPR 0 END; PROC IsNumber = (CHAR ch) BOOL: BEGIN BOOL result; IF (ch >= '0') AND (ch <= '9') THEN result := TRUE ELSE result := FALSE FI; result END; PROC IsIdChar = (CHAR ch) BOOL: BEGIN BOOL result; IF ((ch >= 'A') AND (ch <= 'Z')) OR ((ch >= 'a') AND (ch <= 'z')) OR IsNumber(ch) OR (ch = '_') THEN result := TRUE ELSE result := FALSE FI; result END; PROC GetSeparator = VOID: BEGIN IF nextChar = ':' THEN nextChar := read; IF nextChar = '=' THEN store_token(tk_ASSIGN, "ASSIGN"); # ASSIGN str OF token := ":="; nextChar := read; ELSE store_token(tk_COLON, "COLON"); # COLON str OF token := ":"; FI; ELIF nextChar = '<' THEN nextChar := read; IF nextChar = '=' THEN store_token(tk_LEQ, "LEQ"); # LESSEQUAL str OF token := "<="; nextChar := read; ELSE store_token(tk_LESS, "LESS"); str OF token := "<"; # LESS FI; ELIF nextChar = '>' THEN nextChar := read; IF nextChar = '=' THEN store_token(tk_GEQ, "GEQ"); # GREATEREQUAL str OF token := ">="; nextChar := read; ELSE store_token(tk_GREATER, "GREATER"); # GREATER str OF token := ">"; FI; ELIF nextChar = '/' THEN nextChar := read; IF nextChar = '=' THEN store_token(tk_NEQ, "NEQ"); # NOTEQUAL str OF token := "/="; nextChar := read; ELSE store_token(tk_DIV, "DIV"); # DIV str OF token := "/"; FI; ELIF nextChar = '=' THEN nextChar := read; store_token(tk_EQUAL, "EQUAL"); # EQUAL str OF token := "="; ELIF nextChar = '*' THEN nextChar := read; IF nextChar = '*' THEN store_token(tk_POWER, "POWER"); # POWER str OF token := "**"; nextChar := read; ELSE store_token(tk_MULT, "MULT"); # MULT str OF token := "*"; FI; ELIF nextChar = '+' THEN nextChar := read; store_token(tk_PLUS, "PLUS"); # PLUS str OF token := "+"; ELIF nextChar = '-' THEN nextChar := read; store_token(tk_MINUS, "MINUS"); # MINUS str OF token := "-"; ELIF nextChar = '|' THEN nextChar := read; store_token(tk_PIPE, "PIPE"); # PIPE str OF token := "|"; ELIF nextChar = '[' THEN nextChar := read; store_token(tk_LBRACKET, "LBRACKET"); # LEFT BRACKET str OF token := "["; ELIF nextChar = ']' THEN nextChar := read; store_token(tk_RBRACKET, "RBRACKET"); # RIGHT BRACKET str OF token := "]"; ELIF nextChar = '(' THEN nextChar := read; store_token(tk_LPARENTH, "LPARENTH"); # LEFT PARENTHESIS str OF token := "("; ELIF nextChar = ')' THEN nextChar := read; store_token(tk_RPARENTH, "RPARENTH"); # RIGHT PARENTHESIS str OF token := ")"; ELIF nextChar = ';' THEN nextChar := read; store_token(tk_SEMICOLON, "SEMICOLON"); # SEMI-COLON str OF token := ";"; ELIF nextChar = ',' THEN nextChar := read; store_token(tk_COMMA, "COMMA"); # COMMA str OF token := ","; ELSE prints("GetSeparator: UNEXPECTED ERROR!"); printn; FI; END; PROC GetNextToken = VOID: BEGIN INT i := 0; IF debug_stepwise THEN debugger FI; WHILE IsBlank(nextChar) OR nextChar = '#' DO WHILE IsBlank(nextChar) DO # Handle WHITE SPACE nextChar := read; OD; IF nextChar = '#' THEN # Handle COMMENTS nextChar := read; WHILE nextChar /= '\n' DO nextChar := read OD; nextChar := read; ELIF nextChar = '@' THEN nextChar := read; IF nextChar = '+' THEN debug_echo := TRUE; nextChar := read; ELIF nextChar = '-' THEN debug_echo := FALSE; nextChar := read; ELSE debugger; FI; ELSE 1; FI; OD; # CAUTION: this is EOF IF nextChar = REPR 0 THEN store_token(tk_EOF, "EOF"); ELIF IsSeparator(nextChar) THEN # Handle SEPARATORS GetSeparator; ELIF nextChar = '\"' THEN # Handle STRING constants store_token(tk_STRCONST, "STRCONST"); (str OF token)[i] := nextChar; i := i + 1; nextChar := read; WHILE nextChar /= '\"' DO (str OF token)[i] := nextChar; i := i + 1; IF nextChar = '\\' THEN (str OF token)[i] := read; i := i + 1; FI; nextChar := read; OD; (str OF token)[i] := nextChar; (str OF token)[i+1] := REPR 0; nextChar := read; ELIF nextChar = '\'' THEN # Handle CHAR constants (str OF token)[i] := nextChar; i := i + 1; nextChar := read; IF nextChar = '\\' THEN # store backslash (str OF token)[i] := nextChar; i := i + 1; nextChar := read; FI; (str OF token)[i] := nextChar; # store char i := i + 1; nextChar := read; IF nextChar /= '\'' THEN # store backslash store_token(tk_ERROR, "ERROR"); (str OF token)[i] := nextChar; (str OF token)[i+1] := REPR 0; # printf("%s: ERROR: invalid char constant\n",str OF token); ELSE (str OF token)[i] := nextChar; (str OF token)[i+1] := REPR 0; store_token(tk_CHARCONST, "CHARCONST"); FI; nextChar := read; ELIF IsNumber(nextChar) THEN # Handle INTEGER constants store_token(tk_INTCONST, "INTCONST"); WHILE IsNumber(nextChar) DO (str OF token)[i] := nextChar; i := i + 1; nextChar := read; OD; (str OF token)[i] := REPR 0; ELIF IsIdChar(nextChar) THEN # Handle IDENTIFIERS WHILE IsIdChar(nextChar) DO (str OF token)[i] := nextChar; i := i + 1; nextChar := read; OD; (str OF token)[i] := REPR 0; GetTokenId; ELSE # ERROR store_token(tk_ERROR, "ERROR"); (str OF token)[0] := nextChar; (str OF token)[1] := REPR 0; nextChar := read; FI; used OF token := FALSE; END; [3]INT set_elif_else_fi; set_elif_else_fi[0] := tk_ELIF; set_elif_else_fi[1] := tk_ELSE; set_elif_else_fi[2] := tk_FI; [6]INT set_constants; set_constants[0] := tk_INTCONST; set_constants[1] := tk_CHARCONST; set_constants[2] := tk_STRCONST; set_constants[3] := tk_TRUE; set_constants[4] := tk_FALSE; set_constants[5] := tk_NIL; [5]INT set_arithm_operators; set_arithm_operators[0] := ABS '*'; set_arithm_operators[1] := ABS '/'; set_arithm_operators[2] := tk_MOD; set_arithm_operators[3] := ABS '+'; set_arithm_operators[4] := ABS '-'; set_arithm_operators[5] := tk_POWER; [4]INT set_bool_operators; set_bool_operators[0] := tk_OR; set_bool_operators[1] := tk_OR; set_bool_operators[2] := tk_AND; set_bool_operators[3] := tk_AND; [6]INT set_rel_operators; set_rel_operators[0] := ABS '='; set_rel_operators[1] := tk_NEQ; set_rel_operators[2] := ABS '<'; set_rel_operators[3] := ABS '>'; set_rel_operators[4] := tk_LEQ; set_rel_operators[5] := tk_GEQ; [4]INT set_first_amode; set_first_amode[0] := tk_AMODE; set_first_amode[1] := tk_REF; set_first_amode[2] := ABS '['; set_first_amode[3] := tk_STRUCT; # Return operator's priority PROC priority = (INT token_id) INT: BEGIN INT pr; IF token_id = tk_ASSIGN THEN pr := 10 ELIF token_id = tk_OR THEN pr := 20 ELIF token_id = tk_OR THEN pr := 20 ELIF token_id = tk_AND THEN pr := 30 ELIF token_id = tk_AND THEN pr := 30 ELIF token_id = ABS '+' THEN pr := 40 ELIF token_id = ABS '-' THEN pr := 40 ELIF token_id = ABS '*' THEN pr := 50 ELIF token_id = ABS '/' THEN pr := 50 ELIF token_id = tk_MOD THEN pr := 50 ELIF token_id = tk_POWER THEN pr := 60 ELSE pr := 0 FI; pr END; PROC check_token = (INT tokenId) BOOL: BEGIN IF used OF token THEN GetNextToken; FI; # printf("Checking token %s: %i = %i...\n", str OF token, id OF token, tokenId); id OF token = tokenId END; PROC check_tokenset = ([]INT tokenset) BOOL: BEGIN INT i := 0; WHILE i < UPB tokenset AND NOT check_token(tokenset[i]) DO i := i + 1; OD; i < UPB tokenset END; PROC accept_token = (INT tokenId) BOOL: BEGIN BOOL result; IF used OF token THEN GetNextToken FI; IF id OF token = tokenId THEN printf(" %s ", str OF token); used OF token := TRUE; result := TRUE; ELSE error("wrong token"); FI; result END; FORWARD PROC parse_expression = (INT result) INT; # forward declaration FORWARD PROC parse_amode = (REF STRING mode, BOOL array) INT; # forward declaration FORWARD PROC parse_expr_factor = (INT result) INT; # forward declaration # ##################################################################################### # # PARSE series # # ##################################################################################### # PROC parse_series = ([]INT follow_set) INT: BEGIN INT ptr; # printf("\nENTER: series\n"); parse_expression(0); WHILE check_token(ABS ';') AND NOT check_tokenset(follow_set) DO accept_token(ABS ';'); printf("\n"); IF NOT check_tokenset(follow_set) THEN parse_expression(0); FI; OD; # printf("EXIT: series\n"); ptr END; # ##################################################################################### # # PARSE arg_list = expression (, expression)* # # ##################################################################################### # PROC parse_arg_list = VOID: BEGIN INT i; # (printf(" START: arg_list ")); i := 1; parse_expression(0); WHILE check_token(ABS ',') DO accept_token(ABS ','); i := i + 1; parse_expression(0); OD; # (printf(" DONE: arg_list ")); END; # ##################################################################################### # # PARSE param_list = amode IDENTIFIER (, amode IDENTIFIER)* # # ##################################################################################### # PROC parse_param_list = INT: BEGIN STRING mode; INT param, ptr; INT mode_size; mode_size := parse_amode(mode, FALSE); accept_token(tk_ID); WHILE check_token(ABS ',') DO accept_token(ABS ','); mode_size := parse_amode(mode, FALSE); accept_token(tk_ID); OD; # return pointer to first parameter ptr END; # ##################################################################################### # # PARSE structure = amode IDENTIFIER (, amode IDENTIFIER)* # # ##################################################################################### # PROC parse_structure = (REF STRING mode) INT: BEGIN STRING next_mode; INT var, ptr; INT mode_size; mode_size := parse_amode(next_mode, FALSE); mode := next_mode; accept_token(tk_ID); StrAppend(mode, mode, " "); StrAppend(mode, mode, str OF token); WHILE check_token(ABS ',') DO accept_token(ABS ','); StrAppend(mode, mode, ","); mode_size := mode_size + parse_amode(next_mode, FALSE); accept_token(tk_ID); StrAppend(mode, mode, next_mode); StrAppend(mode, mode, " "); StrAppend(mode, mode, str OF token); OD; mode_size END; # ##################################################################################### # # PARSE amode # # ##################################################################################### # PROC parse_amode = (REF STRING mode, BOOL array) INT: BEGIN STRING next_mode; INT mode_size, items; INT ptr; # ------------------------------------------------------------------------------------- # amode -> AMODE # ------------------------------------------------------------------------------------- IF check_token(tk_AMODE) THEN accept_token(tk_AMODE); mode := str OF token; # ------------------------------------------------------------------------------------- # amode -> REF amode # ------------------------------------------------------------------------------------- ELIF check_token(tk_REF) THEN accept_token(tk_REF); parse_amode(next_mode, FALSE); StrAppend(mode, "REF ", next_mode); mode_size := 8; # ------------------------------------------------------------------------------------- # amode -> '[' [expression [':' expression]] ']' amode # ------------------------------------------------------------------------------------- # CAUTION: we assume only one-dimensional arrays, with constant size! ELIF check_token(ABS '[') THEN accept_token(ABS '['); IF NOT check_token(ABS ']') THEN ptr := parse_expression(0); StrAppend(mode, mode, str OF token); items := str2int(str OF token); FI; accept_token(ABS ']'); StrAppend(mode, mode, "] "); StrAppend(mode, mode, next_mode); parse_amode(next_mode, TRUE); # ------------------------------------------------------------------------------------- # amode -> STRUCT '(' param_list ')' # ------------------------------------------------------------------------------------- ELIF check_token(tk_STRUCT) THEN accept_token(tk_STRUCT); accept_token(ABS '('); mode_size := struc_header_size + parse_structure(next_mode); accept_token(ABS ')'); StrAppend(mode, "(", next_mode); StrAppend(mode, mode, ")"); # ------------------------------------------------------------------------------------- # amode -> ERROR # ------------------------------------------------------------------------------------- ELSE error("Unrecognized mode!"); FI; mode_size END; # ########################################################################################## # # PARSE expr_factor_tail -> ( '(' arg_list ')' | '[' expression ']' )* # # ########################################################################################## # PROC parse_expr_factor_tail = (INT lptr) INT: BEGIN INT result := lptr; INT rptr; # (printf("TAIL -> ")); # ------------------------------------------------------------------------------------- # factor_tail -> '(' arg_list ')' # ------------------------------------------------------------------------------------- IF check_token(ABS '(') THEN accept_token(ABS '('); parse_arg_list; accept_token(ABS ')') # ------------------------------------------------------------------------------------- # expression -> '[' expression ']' # ------------------------------------------------------------------------------------- ELIF check_token(ABS '[') THEN accept_token(ABS '['); rptr := parse_expression(0); # parse subscript accept_token(ABS ']'); parse_expr_factor_tail(0); FI; # (printf("<- ")); result END; # ##################################################################################### # # PARSE expr_simple_factor # # ##################################################################################### # PROC parse_expr_simple_factor = (INT iresult) INT: BEGIN INT cond, label, endlabel; STRING name, mode; INT mode_size; INT ptr, lptr, rptr, proc; INT lastlabel; INT val; INT i, n; INT argt; [11]INT args; # CAUTION: This should be max_params + 1 INT result := iresult; # (printf("FACTOR(")); # ------------------------------------------------------------------------------------- # expression -> tk_MODE tk_AMODE '=' amode # ------------------------------------------------------------------------------------- IF check_token(tk_MODE) THEN # (printf("\nSTART: amode\n")); accept_token(tk_MODE); accept_token(tk_AMODE); accept_token(ABS '='); mode_size := parse_amode(mode, FALSE); # ------------------------------------------------------------------------------------- # expression -> tk_AMODE declaration_expr [, declaration_expr]* # declaration_expr -> tk_ID ['=' expression] [tk_ASSIGN expression] # ------------------------------------------------------------------------------------- ELIF check_tokenset(set_first_amode) THEN # (printf("\nSTART: declaration\n")); parse_amode(mode, FALSE); accept_token(tk_ID); IF check_token(ABS '=') THEN accept_token(ABS '='); rptr := parse_expression(0); FI; IF check_token(tk_ASSIGN) THEN accept_token(tk_ASSIGN); rptr := parse_expression(0); FI; WHILE check_token(ABS ',') DO accept_token(ABS ','); accept_token(tk_ID); IF check_token(tk_ASSIGN) THEN accept_token(tk_ASSIGN); rptr := parse_expression(0); FI; OD; # (printf("\nDONE: declaration\n")) # ------------------------------------------------------------------------------------- # expression -> BEGIN series END # ------------------------------------------------------------------------------------- ELIF check_token(tk_BEGIN) THEN accept_token(tk_BEGIN); result := parse_series(tk_END); accept_token(tk_END); parse_expr_factor_tail(0); # ------------------------------------------------------------------------------------- # expression -> '(' series ')' # ------------------------------------------------------------------------------------- ELIF check_token(ABS '(') THEN accept_token(ABS '('); result := parse_series(ABS ')'); accept_token(ABS ')'); result := parse_expr_factor_tail(result); # ---------------------------------------------------------------------------------------------- # expression -> IF series THEN series [ELIF series THEN series]* [ELSE series THEN series] FI # ---------------------------------------------------------------------------------------------- ELIF check_token(tk_IF) THEN # (printf("\nENTER: IF-expression\n")); accept_token(tk_IF); cond := parse_series(tk_THEN); # get the condition value accept_token(tk_THEN); ptr := parse_series(set_elif_else_fi); IF check_token(tk_FI) THEN accept_token(tk_FI); ELSE WHILE check_token(tk_ELIF) DO accept_token(tk_ELIF); cond := parse_series(tk_THEN); # get the condition value accept_token(tk_THEN); ptr := parse_series(set_elif_else_fi); OD; IF check_token(tk_ELSE) THEN accept_token(tk_ELSE); ptr := parse_series(tk_FI); FI; accept_token(tk_FI); FI; parse_expr_factor_tail(0); # (printf("\nEXIT: IF-expression\n")); # ------------------------------------------------------------------------------------- # expression -> WHILE series DO series OD # ------------------------------------------------------------------------------------- ELIF check_token(tk_WHILE) THEN # (printf("\nENTER: WHILE-expression\n")); accept_token(tk_WHILE); cond := parse_series(tk_DO); # get the condition value parse_series(tk_DO); # CAUTION: fix return value! accept_token(tk_DO); parse_series(tk_OD); accept_token(tk_OD); parse_expr_factor_tail(0); # (printf("\nEXIT: WHILE-expression\n")); # ------------------------------------------------------------------------------------- # expression -> FORWARD PROC IDENTIFIER '=' ['(' param_list ')'] amode ':' expression # ------------------------------------------------------------------------------------- ELIF check_token(tk_FORWARD) THEN # (printf("\nENTER: procedure declaration\n")); accept_token(tk_FORWARD); accept_token(tk_PROC); accept_token(tk_ID); accept_token(ABS '='); IF check_token(ABS '(') THEN accept_token(ABS '('); ptr := parse_param_list; accept_token(ABS ')') FI; mode_size := parse_amode(mode, FALSE); # (printf("\nEXIT: procedure declaration\n")); # ------------------------------------------------------------------------------------- # expression -> PROC IDENTIFIER '=' ['(' param_list ')'] amode ':' expression # ------------------------------------------------------------------------------------- ELIF check_token(tk_PROC) THEN # (printf("\nENTER: procedure declaration\n")); accept_token(tk_PROC); accept_token(tk_ID); accept_token(ABS '='); IF check_token(ABS '(') THEN accept_token(ABS '('); ptr := parse_param_list; accept_token(ABS ')') FI; mode_size := parse_amode(mode, FALSE); # (printf("\nNOW: procedure body\n")); accept_token(ABS ':'); result := parse_expression(result); # expression value = return value # (printf("\nEXIT: procedure declaration\n")); # ------------------------------------------------------------------------------------- # expression -> UPB expression # ------------------------------------------------------------------------------------- ELIF check_token(tk_UPB) THEN accept_token(tk_UPB); ptr := parse_expr_simple_factor(0); # ------------------------------------------------------------------------------------- # expression -> REPR expression # ------------------------------------------------------------------------------------- ELIF check_token(tk_REPR) THEN accept_token(tk_REPR); ptr := parse_expr_simple_factor(0); # ------------------------------------------------------------------------------------- # expression -> ABS expression # ------------------------------------------------------------------------------------- ELIF check_token(tk_ABS) THEN accept_token(tk_ABS); result := parse_expr_simple_factor(result); # ------------------------------------------------------------------------------------- # expression -> NOT expression # ------------------------------------------------------------------------------------- ELIF check_token(tk_NOT) THEN accept_token(tk_NOT); parse_expr_factor; # ------------------------------------------------------------------------------------- # expression -> IDENTIFIER expr_factor_tail # ------------------------------------------------------------------------------------- ELIF check_token(tk_ID) THEN accept_token(tk_ID); IF check_token(tk_OF) THEN result := 0; # Field selector ELSE parse_expr_factor_tail(0); FI; # ------------------------------------------------------------------------------------- # expression -> INTCONST # ------------------------------------------------------------------------------------- ELIF check_token(tk_INTCONST) THEN accept_token(id OF token); # ------------------------------------------------------------------------------------- # expression -> CHARCONST # ------------------------------------------------------------------------------------- ELIF check_token(tk_CHARCONST) THEN accept_token(id OF token); # ------------------------------------------------------------------------------------- # expression -> STRCONST # ------------------------------------------------------------------------------------- ELIF check_token(tk_STRCONST) THEN accept_token(id OF token); # ------------------------------------------------------------------------------------- # expression -> BOOLCONST # ------------------------------------------------------------------------------------- ELIF check_token(tk_TRUE) OR check_token(tk_FALSE) THEN accept_token(id OF token); # ------------------------------------------------------------------------------------- # expression -> NIL # ------------------------------------------------------------------------------------- ELIF check_token(tk_NIL) THEN accept_token(id OF token); FI; # (printf(")")); result END; # ##################################################################################### # # PARSE expr_factor # # ##################################################################################### # PROC parse_expr_factor = (INT result) INT: BEGIN INT lptr, rptr; # ------------------------------------------------------------------------------------- # expression -> expr_simple_factor tk_OF expr_factor # ------------------------------------------------------------------------------------- lptr := parse_expr_simple_factor(result); IF check_token(tk_OF) THEN accept_token(tk_OF); rptr := parse_expr_factor(0); FI; lptr END; # ##################################################################################### # # PARSE arithm_term - handle arithmetic/boolean operators # # ##################################################################################### # PROC parse_arithm_term = (INT delim_op, INT lptr) INT: BEGIN INT new_delim_op, op; INT rptr, ptr := lptr; BOOL done := FALSE; # --------------------------------------------------------------------------------------- # # Case A: INTEGERS (operators: +, -, *, /, **) # # --------------------------------------------------------------------------------------- # IF check_tokenset(set_arithm_operators) THEN new_delim_op := id OF token; op := new_delim_op; WHILE check_tokenset(set_arithm_operators) AND priority(op) = priority(new_delim_op) DO accept_token(op); rptr := parse_expr_factor(0); ptr := rptr; check_tokenset(set_arithm_operators); op := id OF token; IF priority(op) > priority(new_delim_op) THEN # (printf("(")); rptr := parse_arithm_term(new_delim_op, rptr); op := id OF token; # (printf(")")); ELIF priority(op) > priority(delim_op) THEN new_delim_op := op; FI; OD; FI; # report# (printf("\nFINISHED WITH BLOCK %c WITH VALUE %i\n", new_delim_op, val)); ptr END; # ##################################################################################### # # PARSE relop_expr - handle relational operators # # ##################################################################################### # PROC parse_relop_expr = (INT result) INT: BEGIN INT op; INT lptr, rptr, ptr; lptr := parse_arithm_term(0, parse_expr_factor(result)); IF check_tokenset(set_rel_operators) THEN op := id OF token; accept_token(op); # val := calc(op, val, parse_arithm_term(0, parse_expr_factor)) rptr := parse_arithm_term(0, parse_expr_factor(0)); lptr := ptr; FI; lptr END; # ##################################################################################### # # PARSE bool_expr - handle boolean operators # # ##################################################################################### # PROC parse_bool_expr = (INT result) INT: BEGIN INT op; INT lptr, rptr, ptr; lptr := parse_relop_expr(result); WHILE check_tokenset(set_bool_operators) DO op := id OF token; accept_token(op); # val := calc(op, val, parse_relop_expr(0)) rptr := parse_relop_expr(0); lptr := ptr OD; lptr END; # ##################################################################################### # # PARSE expression # # ##################################################################################### # PROC parse_expression = (INT result) INT: BEGIN INT lptr, rptr; # (printf("\nSTART expression\n")); lptr := parse_bool_expr(result); IF check_token(tk_ASSIGN) THEN accept_token(tk_ASSIGN); rptr := parse_bool_expr(0); FI; # printf("\nDONE expression\n"); lptr END; STRING filename := argv[1]; CHAR ch; INT i; IF open(1, filename) = 0 THEN printf("Parsing file %s...\n", filename); nextChar := ' '; GetNextToken; parse_expression(0); printf("\nDone!\n"); close(1); ELSE printf("Error: file %s not found!\n", filename); FI; END