#include #include #include "token.h" #include "buffer.h" #include "symbolTable.h" using namespace std; extern SymbolTableT symbolTable; int FailFunction(BufferT & buffer, int & state); bool GetRelop(TokenT & token, BufferT & buffer, int & state); bool GetID(TokenT & token, BufferT & buffer, int & state); bool GetNumber(TokenT & token, BufferT & buffer, int & state); bool GetWhitespace(BufferT & buffer, int & state); TokenT Scanner() { TokenT x; static BufferT buffer("test"); char c; int state=0; bool fail; bool bad=false; while (state < 25) { //cout << "Top of the loop, state = " << state << endl; switch (state) { case 0: fail=GetRelop(x,buffer,state); break; case 9: fail = GetID(x, buffer, state); break; case 12: fail = GetNumber(x, buffer, state); break; case 22: fail = GetWhitespace(buffer, state); break; default: cout << "Unknown State in scanner " << endl; } if (fail) { bad = FailFunction(buffer, state); } else { // logic to not return a lexeme on whitespace if (state != 24) { state = 26; } else { state = 0; } } } if (bad) { x.first = NONE; if (EOF != buffer.NextLetter()) { cout << "Error in scanner." << endl; } } return x; } int FailFunction(BufferT & buffer, int & state){ if (state < 9) { // tried to read a realop but failed buffer.ResetForward(); state = 9; } else if (state < 12) { // tried an id too, but failed. buffer.ResetForward(); state = 12; } else if (state < 22) { // tried to read a number too but failed buffer.ResetForward(); state = 22; } else { // tried a white space as well. Broken state = 100; return true; } return false; } bool GetRelop(TokenT & token, BufferT & buffer, int & state){ char c; token.first=RELOP; while(1) { switch (state) { case 0: // read a letter, go to states 1,5, 6 c = buffer.NextLetter(); switch (c) { case '<': state = 1; break; case '=': state = 5; break; case '>': state = 6; break; default: return true; } break; case 1: // we have a < , grab another letter. c = buffer.NextLetter(); switch(c) { case '=': state = 2; break; case '>': state = 3; break; default: state = 4; break; } break; case 2: // we have <= token.second.opid=LE; buffer.GetLexeme(); return false; case 3: // we have <> token.second.opid=NE; buffer.GetLexeme(); return false; case 4: // we have < token.second.opid=LT; buffer.RetractForward(); buffer.GetLexeme(); return false; case 5: // saw a = return it. token.second.opid=EQ; buffer.GetLexeme(); return false; case 6: // check for >= state 7 or > state 8; c = buffer.NextLetter(); switch (c) { case '=': state = 7; break; default: state = 8; break; } case 7: // saw >= token.second.opid=GE; buffer.GetLexeme(); return false; case 8: //saw >? token.second.opid=GT; buffer.RetractForward(); buffer.GetLexeme(); return false; default: // who knows return true; } } return true; } bool GetID(TokenT & token, BufferT & buffer, int & state){ char c; string key; token.first=ID; while(1) { //cout << "Top of the loop, state = " << state << endl; switch(state) { case 9: // need an alpha. c = buffer.NextLetter(); if (isalpha(c)) { state = 10; } else { return true; } break; case 10: c = buffer.NextLetter(); if (isalpha(c) or isdigit(c)) { state = 10; } else { state = 11; } break; case 11: buffer.RetractForward(); key = buffer.GetLexeme(); // insert if needed if (not symbolTable.IsPresent(key) ) { symbolTable.Insert(key,ID); } token.first=symbolTable.Token(key); // add pointer to ste if an id if (token.first == ID) { token.second.symbolInfo = symbolTable.Entry(key); } return false; default: return false; } } return true; } bool GetNumber(TokenT & token, BufferT & buffer, int & state){ char c; string key; token.first=NUMBER; while(1) { switch (state) { case 12: c = buffer.NextLetter(); if (isdigit(c) ) { state = 13; } else { return true; } break; case 13: c = buffer.NextLetter(); if (isdigit(c) ) { state = 13; } else if (c == '.') { state = 14; } else if (c=='E') { state = 16; } else { state = 20; } break; case 14: c = buffer.NextLetter(); if (isdigit(c) ) { state = 15; } else { return true; } break; case 15: c = buffer.NextLetter(); if (isdigit(c) ) { state = 15; } else if (c == 'E') { state = 16; } else { state = 15; } break; case 16: c = buffer.NextLetter(); if (isdigit(c) ) { state = 18; } else if (c == '+' or c == '-') { state = 17; } else { return true; } break; case 17: c = buffer.NextLetter(); if (isdigit(c) ) { state = 18; } else { return true; } break; case 18: c = buffer.NextLetter(); if (isdigit(c) ) { state = 18; } else { state = 19; } break; case 19: case 20: case 21: buffer.RetractForward(); key = buffer.GetLexeme(); if (not symbolTable.IsPresent(key)) { symbolTable.Insert(key,NUMBER); } token.second.symbolInfo = symbolTable.Entry(key); return false; default: return true; } } } bool GetWhitespace(BufferT & buffer, int & state){ char c; while (1) { switch (state) { case 22: c = buffer.NextLetter(); if (isspace(c)) { state = 23; } else { return true; } break; case 23: c = buffer.NextLetter(); if (isspace(c)) { state = 23; } else { state = 24; } break; case 24: buffer.RetractForward(); buffer.GetLexeme(); //cout << "Whitespace " << buffer.GetLexeme() << endl;; return false; default:return true; } } }