/***** * * Michael Riff * Scanner software version 1.0 10 Jun 2015. * * Diese Datei implementiert die lexikalische Analyse als separate Routine wie es * bei de Werkzeuge Yacc & Lex gemacht wird. * Diese Verion der SW identifiziert direckt die Zeichen in dem Eingangstext. * * Dies ist noch ein Prototyp, so ist der Test Kode sowie Laufzeitmessungs Kode * mit enthalten. * *****/ //#define RESER_WD #include #include #include #ifdef RESER_WD #include #endif //typedef enum { string, integer, floating, operator, openexpr, closeexpr, opencode, endcode, separator } status_type; typedef enum { string, integer, floating, operator, openexpr, closeexpr, opencode, endcode, semicol, separator #ifndef RESER_WD } token_type; #else , and, or, xor, not, leth, geth, lth, gth, t_if, t_else, t_for, t_while, t_do } token_type; #endif typedef struct { char *text; unsigned int length; } text_token; typedef union { text_token str_val; double flt_val; int int_val; } lex_buf_type; lex_buf_type yyval; //token_type token; unsigned int position; unsigned char *input; char akt; int Init_Lex(char *data) { position = 0; input = (unsigned char*)data; akt = input[position++]; return 0; } /* For performance reason, we do not copy the strings in a null terminated buffer, but use a pointer to the start and a length value. For this we have to use adapted routines Routine used here to convert to integer */ int c2int(text_token value) { int result = 0; int idx; int sgn=1; idx = 0; if ('-'==value.text[idx]) { sgn = -1; idx++; } if ('+'==value.text[idx]) idx++; for(; idx= 65 && akt <= 90 || akt >= 97 && akt <= 122 || akt == '_') { /* Buchstabe A-Z a-z */ mode = string; yyval.str_val.text = (char*)input+position-1; /* Ganzes Wort auslesen. */ while(akt >= 48 && akt <= 57 || akt >= 65 && akt <= 90 || akt >= 97 && akt <= 122 || akt == '_') { akt = input[position++]; } yyval.str_val.length = (char*)input+position-1 - yyval.str_val.text; #ifdef RESER_WD if (!strncmp("and",yyval.str_val.text,3)) { mode = and; } else if (!strncmp("or",yyval.str_val.text,2)) { mode = or; } else if (!strncmp("xor",yyval.str_val.text,3)) { mode = xor; } else if (!strncmp("not",yyval.str_val.text,3)) { mode = not; } else if (!strncmp("leth",yyval.str_val.text,4)) { mode = leth; } else if (!strncmp("geth",yyval.str_val.text,4)) { mode = geth; } else if (!strncmp("lth",yyval.str_val.text,3)) { mode = lth; } else if (!strncmp("gth",yyval.str_val.text,3)) { mode = gth; } else if (!strncmp("if",yyval.str_val.text,2)) { mode = t_if; } else if (!strncmp("else",yyval.str_val.text,4)) { mode = t_else; } else if (!strncmp("for",yyval.str_val.text,4)) { mode = t_for; } else if (!strncmp("while",yyval.str_val.text,5)) { mode = t_while; } else if (!strncmp("do",yyval.str_val.text,2)) { mode = t_do; } #endif } else if ((akt>=48 && akt<=57)) { /* 0-9 */ mode = integer; yyval.str_val.text = (char*)input+position-1; /* Ganze Nummer auslesen. */ while((akt>=48 && akt<=57)) { akt = input[position++]; } if (akt == '.') { mode = floating; akt = input[position++]; while((akt>=48 && akt<=57)) { akt = input[position++]; } // Check for exponenent if ('e'==akt || 'E'==akt) { akt = input[position++]; if ('-'==akt) akt = input[position++]; while((akt>=48 && akt<=57)) { akt = input[position++]; } } } yyval.str_val.length = (char*)input+position-1 - yyval.str_val.text; if (mode == integer) { yyval.int_val = c2int(yyval.str_val); } else { yyval.flt_val = c2float(yyval.str_val); } } else if (akt == '.') { /* . */ mode = floating; yyval.str_val.text = (char*)input+position-1; /* Ganze Nummer auslesen. */ akt = input[position++]; while((akt>=48 && akt<=57)) { akt = input[position++]; } // Check for exponenent if ('e'==akt || 'E'==akt) { akt = input[position++]; if ('-'==akt) akt = input[position++]; while((akt>=48 && akt<=57)) { akt = input[position++]; } } yyval.str_val.length = (char*)input+position-1 - yyval.str_val.text; yyval.flt_val = c2float(yyval.str_val); } else if(akt == '+' || /* 43 */ akt == '-') { /* 45 */ mode = operator; yyval.str_val.text = (char*)input+position-1; akt = input[position++]; // check if we do not have a unary operator preceeding a variable. In this case the operator is separated from the variable name! /* if (akt >= 65 && akt <= 90 || akt >= 97 && akt <= 122 || akt == '_') { mode = string; * Ganzes Wort auslesen. * while(akt >= 48 && akt <= 57 || akt >= 65 && akt <= 90 || akt >= 97 && akt <= 122 || akt == '_') { akt = input[position++]; } yyval.str_val.length = (char*)input+position-1 - yyval.str_val.text; } else */ // check if we do not have a unary operator preceeding numeric value. if (akt >= 48 && akt <= 57) { mode = integer; while((akt>=48 && akt<=57)) { akt = input[position++]; } if (akt == '.') { mode = floating; akt = input[position++]; while((akt>=48 && akt<=57)) { akt = input[position++]; } yyval.str_val.length = (char*)input+position-1 - yyval.str_val.text; yyval.flt_val = c2float(yyval.str_val); } else { yyval.str_val.length = (char*)input+position-1 - yyval.str_val.text; yyval.int_val = c2int(yyval.str_val); } } else { // Check for further operator characters of the operator if (akt == '=' || akt == '+' || akt == '-') { akt = input[position++]; } yyval.str_val.length = (char*)input+position-1 - yyval.str_val.text; } } else if(akt == '*' || /* 42 */ akt == '/' || /* 47 */ akt == '^') { /* 94 */ mode = operator; yyval.str_val.text = (char*)input+position-1; // Check for further operator characters of the operator if (*(input+position) == '=') { akt = input[position++]; } yyval.str_val.length = (char*)input+position - yyval.str_val.text; akt = input[position++]; } else if (akt == '=' || // 61 akt == '<' || // 60 akt == '>' || // 61 akt == '!') { // 33 mode = operator; yyval.str_val.text = (char*)input+position-1; // Check for further operator characters of the operator if (*(input+position) == '=') { akt = input[position++]; yyval.str_val.length = 2; } else { yyval.str_val.length = 1; } akt = input[position++]; } else if (akt == 40) { // '(' mode = openexpr; akt = input[position++]; } else if (akt == 41) { // ')' mode = closeexpr; akt = input[position++]; } else if (akt == '{') { // 123 mode = opencode; akt = input[position++]; } else if (akt == '}') { // 125 mode = endcode; akt = input[position++]; } else if (akt == ';') { // 59 mode = semicol; akt = input[position++]; } else { mode = -1; } // Suppress separator characters while (akt==' ' || akt=='\n' || akt=='\r' || akt=='\t') { akt = input[position++]; } return mode; } /* TEST CODE */ char buffer[20]; void print(text_token value) { int lgth; for(lgth=0; lgth //TMTask TimeData; #include struct ExtendedTimerRec { TMTask tmTask; ProcessSerialNumber taskPSN; }; typedef struct ExtendedTimerRec ExtendedTimerRec, *ExtendedTimerPtr; ExtendedTimerRec TimeData; Boolean called; pascal void dummyTask() { called = true; // WakeUpProcess(&((ExtendedTimerRec) TimeData).taskPSN); WakeUpProcess(&(TimeData).taskPSN); } /* short dummyTask() { called = true; WakeUpProcess(&((ExtendedTimerRec) TimeData).taskPSN); } */ typedef struct { token_type tok; char text[15]; int iVal; double fVal; } Entry_Type; Entry_Type Code[100]; int numTok; #endif int main() { #ifdef PRFORMANCE int idx; #endif printf("Lexer test\n"); Init_Lex(test_data); #ifdef PRFORMANCE numTok = 0; called = false; TimeData.tmTask.qLink = NULL; TimeData.tmTask.qType = 0; // TimeData.tmAddr = NewTimerProc(dummyTask); TimeData.tmTask.tmAddr = NewTimerProc(dummyTask); TimeData.tmTask.tmCount = 0; //TimeData.tmTask.tmWakeup = 0; TimeData.tmTask.tmReserved = 0; // InsTime(&TimeData); GetCurrentProcess(&TimeData.taskPSN); InsXTime((QElemPtr) &TimeData.tmTask); // PrimeTime(&TimeData, 1500); PrimeTime((QElemPtr) &TimeData.tmTask, 1500); #endif token = yylex(); do { #ifdef PRFORMANCE Code[numTok].tok = token; #endif switch(token) { #ifndef PRFORMANCE case string: printf("Str "); print(yyval.str_val); printf("\n"); break; case integer: printf("Int %d\n", yyval.int_val); break; case floating: printf("Ftl %f\n", yyval.flt_val); // printf("Ftl %g\n", yyval.flt_val); break; case operator: printf("Op "); print(yyval.str_val); printf("\n"); break; case openexpr: printf("Parenth (\n"); break; case closeexpr: printf("Parenth )\n"); break; case opencode: printf("{\n"); break; case endcode: printf("}\n"); break; case separator: printf("Sep\n"); break; case semicol: printf("Stop ;\n"); break; default: printf("-> other token %d \n"); #else case string: BlockMove("Str ", (Code[numTok].text), 4); BlockMove(yyval.str_val.text, Code[numTok].text+4, yyval.str_val.length); Code[numTok].text[yyval.str_val.length] = 0; numTok++; break; case integer: BlockMove("Int ", (Code[numTok].text), 5); Code[numTok].iVal = yyval.int_val; numTok++; break; case floating: BlockMove("Ftl ", (Code[numTok].text), 5); Code[numTok].fVal = yyval.flt_val; numTok++; break; case operator: BlockMove("Op ", (Code[numTok].text), 3); BlockMove(yyval.str_val.text, (Code[numTok].text+3), yyval.str_val.length); Code[numTok].text[yyval.str_val.length+3] = 0; numTok++; break; case openexpr: BlockMove("Parenth (", (Code[numTok].text), 10); numTok++; break; case closeexpr: BlockMove("Parenth )", (Code[numTok].text), 10); numTok++; break; case opencode: Code[numTok].text[0] = '{'; numTok++; break; case endcode: Code[numTok].text[0] = '}'; numTok++; break; case separator: BlockMove("Sep ", (Code[numTok].text), 4); numTok++; break; case semicol: BlockMove("Stop ;", (Code[numTok].text), 6); numTok++; break; default: printf("-> other token %d \n"); #endif } token = yylex(); } while (-1 != token && 0xFF != token); #ifdef PRFORMANCE // RmvTime(&TimeData); // Immediately stop it. Unused time returned in negated microsecs RmvTime((QElemPtr)&TimeData.tmTask); // Immediately stop it. Unused time returned in negated microsecs if (called) { printf("Timeout happened!!"); } else { // printf("Rem time %d", TimeData.tmCount); printf("Rem time %d %d\n", numTok, TimeData.tmTask.tmCount); for (idx=0;idx other token %d \n"); } } } #endif return EXIT_SUCCESS; }