#include "global.h" #include "list.h" #include "source.h" #include "lex.h" #include "parser.h" #include "irep.h" #include "lexparse.h" #include "fsa.h" #include "fsatab.h" // The constructor function for FsaTable converts the FSA transitions // into a table form for convenient output. FsaTable::FsaTable(list *x) { int offset = 0; listIter each(x); odfsaState **s; Transition *t; maxChar = (Transition::maxChar > 127 ? 255 : 127); states = x->length(); table = (short int **) allocate(states * sizeof(short int *)); final = (LexRule **) allocate(states * sizeof(LexRule *)); for (int i=0; iid(); if (odfsaState::initialPartition == (*s)) initState = (*s)->id() - offset; final[i] = (*s)->associatedToken(); for (int j=1; j<=maxChar; j++) { t = (*s)->transitions.findTrigger(j); table[i][j-1] = (t ? t->destination()->id() - offset: -1); } } } // The following are member functions for printing out appropriate code // fragements in response to the predetermined markers in the template // file. void FsaTable::pr_nomodsWarning(FILE *ofdes) { fprintf(ofdes, "This is a generated file. Modifications are futile."); } void FsaTable::pr_initialState(FILE *ofdes) { fprintf(ofdes, "%d", initState); } void FsaTable::pr_states(FILE *ofdes) { fprintf(ofdes, "%d", states); } void FsaTable::pr_charSet(FILE *ofdes) { fprintf(ofdes, "%d", maxChar+2); } void FsaTable::pr_finalStates(FILE *ofdes) { fprintf(ofdes, "{\n"); for (int i=0; iisIgnored()) fprintf(ofdes, "\t{ 0, "); else fprintf(ofdes, "\t{ %s, ", final[i]->name()); if (final[i]->filter()) fprintf(ofdes, "_fil_%s }", final[i]->name()); else fprintf(ofdes, "0 }"); } else fprintf(ofdes, "\t{ -1, 0 }"); } fprintf(ofdes, "}"); } void FsaTable::pr_filters(FILE *ofdes) { for (int i=0; ifilter()) { for (int j=0; jname()); fprintf(ofdes, "(GLexer *lex, LexToken &token)\n"); fprintf(ofdes, "{%s\n%s\n}\n", "if (!lex) abort();", final[i]->filter()); skip: ; } } void FsaTable::pr_prelude(FILE *ofdes) { if (LexGenParser::prelude) fprintf(ofdes, "%s\n", LexGenParser::prelude); } void FsaTable::pr_postlude(FILE *ofdes) { if (LexGenParser::postlude) fprintf(ofdes, "%s\n", LexGenParser::postlude); } // The writer class produces formatted tables. This is useful for the // initialisation of large arrays to represent transition functions. class writer { FILE *fdes; int col, first; char buf[16]; public: void print(int); void print(char *); writer(FILE *); ~writer(); }; void FsaTable::pr_stateTransition(FILE *ofdes) { writer v(ofdes); for (int i=0; i 70) { col = 0; fprintf(fdes, "\n"); } fprintf(fdes, "%s", s); } void writer::print(int i) { if (!first) { fprintf(fdes, ", "); col += 2; } first = FALSE; sprintf(buf, "%d", i); col += strlen(buf); if (col > 70) { col = 0; fprintf(fdes, "\n"); } fprintf(fdes, "%s", buf); } writer::writer(FILE *fd) { fdes = fd; col = 0; first = TRUE; fprintf(fdes, "{"); } writer::~writer() { fprintf(fdes, "}"); }