void FACTOR() { if(TOKEN == identsym) { symbol current = getSymbol(IDENTIFIER); if(current.kind == 2) { //LOD current.L current.M printToFile(3,lexiLevel-current.level,current.addr); lines++; } else if(current.kind == 1) { //LIT 0 getSymbol().val printToFile(1,0,current.val); lines++; } else { ERROR("Error 21: expression must not contain a procedure identifier."); } GETTOKEN(); } else if(TOKEN == numbersym) { //LIT 0 NUMBER printToFile(1,0,NUMBER); lines++; GETTOKEN(); } else if(TOKEN == lparentsym) { GETTOKEN(); EXPRESSION(); if(TOKEN != rparentsym) { ERROR("Error number 22, right parenthesis missing."); } GETTOKEN(); } else { printf("%d\n", TOKEN); ERROR("Error number 23, the preceding factor cannot begin with this symbol."); } }
void PROGRAM() { GETTOKEN(); BLOCK(); if(TOKEN != periodsym) { ERROR("Error number 9, period expected."); } //the halt at the end of the program printToFile(9, 0, 2); }
void TERM() { FACTOR(); while(TOKEN == multsym || TOKEN == slashsym) { if(TOKEN == multsym) { GETTOKEN(); FACTOR(); //OPR 0 4 printToFile(2,0,4); lines++; } else if(TOKEN == slashsym) { GETTOKEN(); FACTOR(); //OPR 0 5 printToFile(2,0,5); lines++; } } }
yylex(){ int nstr; extern int yyprevious; #ifdef __cplusplus /* to avoid CC and lint complaining yyfussy not being used ...*/ static int __lex_hack = 0; if (__lex_hack) goto yyfussy; #endif while((nstr = yylook()) >= 0) yyfussy: switch(nstr){ case 0: if(yywrap()) return(0); break; case 1: # line 36 "prop.l" ECHO; break; case 2: # line 37 "prop.l" ECHO; break; case 3: # line 38 "prop.l" GETTOKEN(NEWLINE); break; case 4: # line 39 "prop.l" GETTOKEN(THEREFORE); break; case 5: # line 40 "prop.l" GETTOKEN(BICONDITIONAL); break; case 6: # line 41 "prop.l" GETTOKEN(IMPLICATION); break; case 7: # line 42 "prop.l" GETTOKEN(OR); break; case 8: # line 43 "prop.l" GETTOKEN(AND); break; case 9: # line 44 "prop.l" GETTOKEN(NEGATION); break; case 10: # line 45 "prop.l" GETTOKEN(LPAREN); break; case 11: # line 46 "prop.l" GETTOKEN(RPAREN); break; case 12: # line 47 "prop.l" GETTOKEN(COMMA); break; case 13: # line 48 "prop.l" GETTOKEN(SEMICOLON); break; case 14: # line 49 "prop.l" GETTOKEN(QUIT); break; case 15: # line 50 "prop.l" GETTOKEN(TRUE); break; case 16: # line 51 "prop.l" GETTOKEN(FALSE); break; case 17: # line 52 "prop.l" GETTOKEN(IDENTIFIER); break; case 18: # line 53 "prop.l" { ECHO; YYDUMP(); strcpy(yylval.string, yytext); return(*yytext); } break; case -1: break; default: (void)fprintf(yyout,"bad switch yylook %d",nstr); } return(0); }
void BLOCK() { if(TOKEN == constsym) { do { GETTOKEN(); if(TOKEN != identsym) { ERROR("Error number 4, const must be followed by identifier."); } GETTOKEN(); if(TOKEN == becomessym) { ERROR("Error number 1, use = instead of :="); } if(TOKEN != eqlsym) { ERROR("Error number 2, identifier must be followed by ="); } GETTOKEN(); if(TOKEN != numbersym) { ERROR("Error number 3, = must be followed by a number."); } ENTER(1); GETTOKEN(); } while(TOKEN == commasym); if(TOKEN != semicolonsym) { ERROR("Error number 5, semicolon or comma missing."); } GETTOKEN(); } if(TOKEN == varsym) { do { GETTOKEN(); if(TOKEN != identsym) { ERROR("Error number 4, var must be followed by identifier."); } ENTER(2); GETTOKEN(); } while(TOKEN == commasym); if(TOKEN != semicolonsym) { ERROR("Error number 5, semicolon or comma missing."); } GETTOKEN(); } //procedure section (will not be used in module 3) while(TOKEN == procsym) { GETTOKEN(); if(TOKEN != identsym) { ERROR("Error number 4, procedure must be followed by identifier."); } ENTER(3); GETTOKEN(); if(TOKEN != semicolonsym) { ERROR("Error number 6, incorrect symbol after procedure declaration."); } GETTOKEN(); BLOCK(); if(TOKEN != semicolonsym) { //may need to be a different error message ERROR("Error number 5, semicolon or comma missing."); } GETTOKEN(); } //INC O (4+numOfVariables) printToFile(6,0,4+numOfVariables); lines++; STATEMENT(); }
void STATEMENT() { //initialization if(TOKEN == identsym) { //stores the name of the identifier that will be initialized char name[12]; strcpy(name, IDENTIFIER); //if identifier is not a variable, produce error if(getSymbol(IDENTIFIER).kind != 2) { ERROR("Error number 12, assignment to constant or procedure not allowed."); } GETTOKEN(); if(TOKEN != becomessym) { ERROR("Error number 13, assignment operator expected."); } GETTOKEN(); EXPRESSION(); symbol current = getSymbol(name); //STO 0 M printToFile(4,current.level,current.addr); lines++; } //procedure call (not in tiny PL/0) else if(TOKEN == callsym) { GETTOKEN(); if(TOKEN != identsym) { ERROR("Error number 14, call must be followed by an identifier."); } //if the identifier is not a procedure, produce an error if(getSymbol(IDENTIFIER).kind != 3) { ERROR("Error number 15, call of a constant or variable is meaningless."); } GETTOKEN(); } //a group of statements else if(TOKEN == beginsym) { GETTOKEN(); STATEMENT(); while(TOKEN == semicolonsym) { GETTOKEN(); STATEMENT(); } if(TOKEN != endsym) { ERROR("Error number 26, end is expected."); } GETTOKEN(); } else if(TOKEN == ifsym) { GETTOKEN(); CONDITION(); //top of the stack has whether it is true or false if(TOKEN != thensym) { ERROR("Error number 16, then expected."); } //after the condition, count how many instructions are written int currentLines = lines; inConditional++; fpos_t filePos; fgetpos(ifp, &filePos); //loop ensures this is done twice int i; for(i = 0; i < 2; i++) { if(i == 1) { inConditional--; //make branch here (lines contains the line that you jump to if the condition is not met) //printToFile() //JPC 0 M = lines printToFile(8,0,lines); //returns the file to the previous position fsetpos(ifp, &filePos); lines = currentLines; //Lines increment for prinToFile used in for loop //lines++; } lines++; GETTOKEN(); STATEMENT(); } } else if(TOKEN == whilesym) { int jumpBackLine = lines; GETTOKEN(); CONDITION(); //top of the stack has whether it is true or false if(TOKEN != dosym) { ERROR("Error number 18, do expected."); } //after the condition, count how many instructions are written int currentLines = lines; inConditional++; fpos_t filePos; fgetpos(ifp, &filePos); //loop ensures this is done twice int i; for(i = 0; i < 2; i++) { if(i == 1) { inConditional--; //make branch here (lines + 1 contains the line that you jump to if the condition is not met) //printToFile() //JPC 0 M = l printToFile(8,0,lines + 1); //returns the file to the previous position fsetpos(ifp, &filePos); lines = currentLines; //Lines increment for the printToFile used in for loop //lines++; } //the line for the branch is added lines++; GETTOKEN(); STATEMENT(); } //JMP 0 M = jumpBackLines printToFile(7,0,jumpBackLine); lines++; } }
yylex(){ int nstr; extern int yyprevious; #ifdef __cplusplus /* to avoid CC and lint complaining yyfussy not being used ...*/ static int __lex_hack = 0; if (__lex_hack) goto yyfussy; #endif while((nstr = yylook()) >= 0) yyfussy: switch(nstr){ case 0: if(yywrap()) return(0); break; case 1: # line 35 "stab.l" MYECHO; break; case 2: # line 36 "stab.l" MYECHO; break; case 3: # line 37 "stab.l" { MYECHO; YYDUMP(); strcpy(yylval.string, yytext); if (strlen(yytext) == 1) return(*yytext); else return(NAME); } break; case 4: # line 46 "stab.l" GETTOKEN(STRING); break; case 5: # line 47 "stab.l" GETTOKEN(REAL); break; case 6: # line 48 "stab.l" GETTOKEN(INTEGER); break; case 7: # line 49 "stab.l" GETTOKEN(HEXADECIMAL); break; case 8: # line 50 "stab.l" { MYECHO; YYDUMP(); strcpy(yylval.string, yytext); return(*yytext); } break; case -1: break; default: (void)fprintf(yyout,"bad switch yylook %d",nstr); } return(0); }
yylex(){ int nstr; extern int yyprevious; #ifdef __cplusplus /* to avoid CC and lint complaining yyfussy not being used ...*/ static int __lex_hack = 0; if (__lex_hack) goto yyfussy; #endif while((nstr = yylook()) >= 0) yyfussy: switch(nstr){ case 0: if(yywrap()) return(0); break; case 1: # line 46 "otyscan.l" ; break; case 2: # line 47 "otyscan.l" GETTOKEN(NEWLINE); break; case 3: # line 48 "otyscan.l" GETTOKEN(MSGID); break; case 4: # line 49 "otyscan.l" GETTOKEN(TIME); break; case 5: # line 50 "otyscan.l" GETTOKEN(CLASS); break; case 6: # line 51 "otyscan.l" GETTOKEN(ACTION); break; case 7: # line 52 "otyscan.l" GETTOKEN(OUTPRIOR); break; case 8: # line 53 "otyscan.l" GETTOKEN(FREQ); break; case 9: # line 54 "otyscan.l" GETTOKEN(PROTOTYPE); break; case 10: # line 55 "otyscan.l" GETTOKEN(FIELD); break; case 11: # line 56 "otyscan.l" GETTOKEN(FIELDUP); break; case 12: # line 57 "otyscan.l" GETTOKEN(NPVAL); break; case 13: # line 58 "otyscan.l" GETTOKEN(WIDTH); break; case 14: # line 59 "otyscan.l" GETTOKEN(ENUM); break; case 15: # line 60 "otyscan.l" GETTOKEN(OUTPUT); break; case 16: # line 61 "otyscan.l" { YYDUMP(); VERBOSE(stdout, "otyscan: %s", yytext+strlen("otypp: ")); } break; case 17: # line 65 "otyscan.l" GETTOKEN(LEFTBRACE); break; case 18: # line 66 "otyscan.l" GETTOKEN(RIGHTBRACE); break; case -1: break; default: (void)fprintf(yyout,"bad switch yylook %d",nstr); } return(0); }
yylex(){ int nstr; extern int yyprevious; #ifdef __cplusplus /* to avoid CC and lint complaining yyfussy not being used ...*/ static int __lex_hack = 0; if (__lex_hack) goto yyfussy; #endif while((nstr = yylook()) >= 0) yyfussy: switch(nstr){ case 0: if(yywrap()) return(0); break; case 1: # line 33 "mybc.l" ; break; case 2: # line 34 "mybc.l" { YYDUMP(); yylval.number.value.lvalue = strtol(yytext, (char **)0, 10); yylval.number.type = LONG; return(LCONST); } break; case 3: # line 40 "mybc.l" { YYDUMP(); yylval.number.value.ulvalue = strtol(yytext+1, (char **)0, 16); yylval.number.type = ULONG; return(ULCONST); } break; case 4: # line 46 "mybc.l" { YYDUMP(); yylval.number.value.ulvalue = strtol(yytext+1, (char **)0, 8); yylval.number.type = ULONG; return(ULCONST); } break; case 5: # line 52 "mybc.l" { YYDUMP(); yylval.number.value.ulvalue = strtol(yytext+1, (char **)0, 2); yylval.number.type = ULONG; return(ULCONST); } break; case 6: # line 58 "mybc.l" { YYDUMP(); #ifdef SUN sscanf(yytext, "%le", &yylval.number.value.dvalue); #else sscanf(yytext, "%e", &yylval.number.value.dvalue); #endif yylval.number.type = DOUBLE; return(DCONST); } break; case 7: # line 68 "mybc.l" GETTOKEN(OR); break; case 8: # line 69 "mybc.l" GETTOKEN(AND); break; case 9: # line 70 "mybc.l" GETTOKEN(BITOR); break; case 10: # line 71 "mybc.l" GETTOKEN(BITXOR); break; case 11: # line 72 "mybc.l" GETTOKEN(BITAND); break; case 12: # line 73 "mybc.l" GETTOKEN(EQUAL); break; case 13: # line 74 "mybc.l" GETTOKEN(NOTEQUAL); break; case 14: # line 75 "mybc.l" GETTOKEN(LT); break; case 15: # line 76 "mybc.l" GETTOKEN(GT); break; case 16: # line 77 "mybc.l" GETTOKEN(LE); break; case 17: # line 78 "mybc.l" GETTOKEN(GE); break; case 18: # line 79 "mybc.l" GETTOKEN(LSHIFT); break; case 19: # line 80 "mybc.l" GETTOKEN(RSHIFT); break; case 20: # line 81 "mybc.l" GETTOKEN(PLUS); break; case 21: # line 82 "mybc.l" GETTOKEN(MINUS); break; case 22: # line 83 "mybc.l" GETTOKEN(STAR); break; case 23: # line 84 "mybc.l" GETTOKEN(SLASH); break; case 24: # line 85 "mybc.l" GETTOKEN(PERCENT); break; case 25: # line 86 "mybc.l" GETTOKEN(LPAREN); break; case 26: # line 87 "mybc.l" GETTOKEN(RPAREN); break; case 27: # line 88 "mybc.l" GETTOKEN(TILDE); break; case 28: # line 89 "mybc.l" GETTOKEN(NOT); break; case 29: # line 90 "mybc.l" GETTOKEN(COMMA); break; case 30: # line 91 "mybc.l" GETTOKEN(HELP); break; case 31: # line 92 "mybc.l" { YYDUMP(); if (strcmp(yytext, "l") == 0) { yylval.type = LONG; return(LCAST); } else if (strcmp(yytext, "ul") == 0) { yylval.type = ULONG; return(ULCAST); } else if (strcmp(yytext, "d") == 0) { yylval.type = DOUBLE; return(DCAST); } else if ((strcmp(yytext, "q") == 0) || (strcmp(yytext, "quit") == 0)) { GETTOKEN(QUIT); } else if (strcmp(yytext, "ob") == 0) { GETTOKEN(OUTBASE); } else if (strcmp(yytext, "exp") == 0) { GETTOKEN(EXP); } else if (strcmp(yytext, "log10") == 0) { GETTOKEN(LOG10); } else if (strcmp(yytext, "log") == 0) { GETTOKEN(LOG); } else if (strcmp(yytext, "pow") == 0) { GETTOKEN(POW); } else if (strcmp(yytext, "sqrt") == 0) { GETTOKEN(SQRT); } else if (strcmp(yytext, "sin") == 0) { GETTOKEN(SIN); } else if (strcmp(yytext, "cos") == 0) { GETTOKEN(COS); } else if (strcmp(yytext, "tan") == 0) { GETTOKEN(TAN); } else if (strcmp(yytext, "asin") == 0) { GETTOKEN(ASIN); } else if (strcmp(yytext, "acos") == 0) { GETTOKEN(ACOS); } else if (strcmp(yytext, "atan") == 0) { GETTOKEN(ATAN); } else if (strcmp(yytext, "help") == 0) { GETTOKEN(HELP); } GETTOKEN(STRING); } break; case 32: # line 168 "mybc.l" GETTOKEN(NEWLINE); break; case 33: # line 169 "mybc.l" { YYDUMP(); strcpy(yylval.string, yytext); return(*yytext); } break; case -1: break; default: (void)fprintf(yyout,"bad switch yylook %d",nstr); } return(0); }
void BLOCK(int enterIntoTable) { lexiLevel++; if(TOKEN == constsym) { do { GETTOKEN(); if(TOKEN != identsym) { ERROR("Error number 4, const must be followed by identifier."); } GETTOKEN(); if(TOKEN == becomessym) { ERROR("Error number 1, use = instead of :="); } if(TOKEN != eqlsym) { ERROR("Error number 2, identifier must be followed by ="); } GETTOKEN(); if(TOKEN != numbersym) { ERROR("Error number 3, = must be followed by a number."); } if(enterIntoTable == 0) { ENTER(1); } GETTOKEN(); } while(TOKEN == commasym); if(TOKEN != semicolonsym) { ERROR("Error number 5, semicolon or comma missing."); } GETTOKEN(); } if(TOKEN == varsym) { do { GETTOKEN(); if(TOKEN != identsym) { ERROR("Error number 4, var must be followed by identifier."); } if(enterIntoTable == 0) { ENTER(2); } GETTOKEN(); } while(TOKEN == commasym); if(TOKEN != semicolonsym) { ERROR("Error number 5, semicolon or comma missing."); } GETTOKEN(); } while(TOKEN == procsym) { GETTOKEN(); if(TOKEN != identsym) { ERROR("Error number 4, procedure must be followed by identifier."); } if(enterIntoTable == 0) { ENTER(3); } GETTOKEN(); if(TOKEN != semicolonsym) { ERROR("Error number 6, incorrect symbol after procedure declaration."); } //saves the current position, for the jmp statement int currentLines = lines; inConditional++; fpos_t filePos; fgetpos(ifp, &filePos); int i; for(i = 0; i < 2; i++) { if(i == 1) { inConditional--; //JMP 0 M = lines printToFile(7,0,lines); //returns the file to the previous position fsetpos(ifp, &filePos); lines = currentLines; } lines++; GETTOKEN(); BLOCK(i+enterIntoTable); //return from the procedure call printToFile(2, 0, 0); lines++; } //semicolon is needed after a procedure if(TOKEN != semicolonsym) { //may need to be a different error message ERROR("Error number 5, semicolon or comma missing."); } GETTOKEN(); } //INC O (4+numOfVariables) printToFile(6,0,4+numOfVariablesInLexiLevel()); lines++; STATEMENT(); lexiLevel--; }
void STATEMENT() { //initialization if(TOKEN == identsym) { //stores the name of the identifier that will be initialized char name[12]; strcpy(name, IDENTIFIER); //if identifier is not a variable, produce error if(getSymbol(IDENTIFIER).kind != 2) { ERROR("Error number 12, assignment to constant or procedure not allowed."); } GETTOKEN(); if(TOKEN != becomessym) { ERROR("Error number 13, assignment operator expected."); } GETTOKEN(); EXPRESSION(); symbol current = getSymbol(name); //STO L M printToFile(4,lexiLevel-current.level,current.addr); lines++; } else if(TOKEN == callsym) { GETTOKEN(); if(TOKEN != identsym) { ERROR("Error number 14, call must be followed by an identifier."); } //if the identifier is not a procedure, produce an error if(getSymbol(IDENTIFIER).kind != 3) { ERROR("Error number 15, call of a constant or variable is meaningless."); } symbol current = getSymbol(IDENTIFIER); //CAL L M printToFile(5, lexiLevel-current.level, current.addr); lines++; GETTOKEN(); } //a group of statements else if(TOKEN == beginsym) { GETTOKEN(); STATEMENT(); while(TOKEN == semicolonsym) { GETTOKEN(); STATEMENT(); } if(TOKEN != endsym) { printf("Line: %d %s\n", lines, IDENTIFIER); ERROR("Error number 26, end is expected."); } GETTOKEN(); } else if(TOKEN == ifsym) { GETTOKEN(); CONDITION(); //top of the stack has whether it is true or false if(TOKEN != thensym) { ERROR("Error number 16, then expected."); } //after the condition, count how many instructions are written int currentLines = lines; inConditional++; fpos_t filePos; fgetpos(ifp, &filePos); //loop ensures this is done twice int i; for(i = 0; i < 2; i++) { if(i == 1) { inConditional--; //JPC 0 M = lines printToFile(8,0,lines); //returns the file to the previous position fsetpos(ifp, &filePos); lines = currentLines; } lines++; GETTOKEN(); STATEMENT(); fpos_t filePos2; fgetpos(ifp, &filePos2); if(TOKEN == semicolonsym) { GETTOKEN(); } //we need another line for the jump if(i == 0 && TOKEN == elsesym) { lines++; } else if(TOKEN != elsesym) { TOKEN = semicolonsym; fsetpos(ifp, &filePos2); } } if(TOKEN == elsesym) { //gets the position of the else currentLines = lines; inConditional++; fgetpos(ifp, &filePos); for(i = 0; i < 2; i++) { if(i == 1) { inConditional--; //jmp end of loop printToFile(7,0,lines); //returns the file to the previous position fsetpos(ifp, &filePos); lines = currentLines; } lines++; GETTOKEN(); STATEMENT(); } } } else if(TOKEN == whilesym) { int jumpBackLine = lines; GETTOKEN(); CONDITION(); //top of the stack has whether it is true or false if(TOKEN != dosym) { ERROR("Error number 18, do expected."); } //after the condition, count how many instructions are written int currentLines = lines; inConditional++; fpos_t filePos; fgetpos(ifp, &filePos); //loop ensures this is done twice int i; for(i = 0; i < 2; i++) { if(i == 1) { inConditional--; //make branch here (lines + 1 contains the line that you jump to if the condition is not met) //printToFile() //JPC 0 M = l printToFile(8,0,lines + 1); //returns the file to the previous position fsetpos(ifp, &filePos); lines = currentLines; //Lines increment for the printToFile used in for loop //lines++; } //the line for the branch is added lines++; GETTOKEN(); STATEMENT(); } //JMP 0 M = jumpBackLines printToFile(7,0,jumpBackLine); lines++; } else if(TOKEN == readsym) { GETTOKEN(); if(TOKEN != identsym) { ERROR("Error number 28, identifier expected after read."); } symbol current = getSymbol(IDENTIFIER); if(current.kind != 2) { ERROR("Error number 29, writing to a constant or procedure is not allowed."); } //SIO 0 1 //STO 0 M printToFile(9, 0, 1); printToFile(4,lexiLevel-current.level,current.addr); lines += 2; GETTOKEN(); } else if(TOKEN == writesym) { GETTOKEN(); if(TOKEN != identsym) { ERROR("Error number 30, identifier expected after write."); } symbol current = getSymbol(IDENTIFIER); if(current.kind == 3) { ERROR("Error number 31, cannot write a procedure."); } if(current.kind == 2) { //LOD L M printToFile(3, lexiLevel-current.level, current.addr); } if(current.kind == 1) { //LIT 0 val printToFile(1, 0, current.val); } //SIO 0 0 printToFile(9, 0, 0); lines +=2; GETTOKEN(); } }