📄 elexscannerdef.cpp
字号:
/* $Id: ElexScannerDef.cpp,v 1.13 1997/05/18 10:54:37 matt Exp $ Elex scanner definition. (c) Jan 96 Matt Phillips. */ #include <ctype.h>#include "ElexScannerDef.h"class ElexScannerDef::CodeStream{public: enum {IndentStep = 2}; CodeStream (ostream &s) : str (s), indents (0) {} ~CodeStream () {} ostream &str; int indents; void indent (); void incIndent () {indents += IndentStep;} void decIndent () {indents -= IndentStep;} void singleAttr (const char *attr, string &value) {indent (); scalarAttr (attr, value); str << endl;} void singleAttr (const char *attr, int value) {indent (); scalarAttr (attr, value); str << endl;} void singleAttr (const string &attr, int value) {indent (); scalarAttr (attr, value); str << endl;} void scalarAttr (const char *attr, const string &value) {str << attr << " \"" << value << '"';} void scalarAttr (const char *attr, int value) {str << attr << " \"" << value << '"';} void scalarAttr (const string &attr, int value) {str << attr << " \"" << value << '"';} void scalarAttr (const string &attr, const string &value) {str << attr << " \"" << value << '"';} void startAttrListValue (const char *name); void endAttrListValue () {decIndent (); indent (); str << "]\n";} void printChar (int chr);};void ElexScannerDef::CodeStream::indent (){ for (int c = indents; c > 0; c--) { str << ' '; }}void ElexScannerDef::CodeStream::startAttrListValue (const char *attrName){ indent (); str << attrName << endl; indent (); str << "[\n"; incIndent ();}void ElexScannerDef::CodeStream::printChar (int chr){ if (chr <= 32 || chr > 127) str.form ("\\%02x", chr); else if (chr == '"') str << "\\\""; else if (chr == '\\') str << "\\\\"; else str << char (chr);}////////////////// ElexScannerDefvoid ElexScannerDef::outputTokens (CodeStream &cs){ if (tokens.nItems () > 0) { int first = 1; cs.indent (); cs.str << "tokens ["; for (Tokens::Iterator i (tokens); i; i++) { if (!first) cs.str << ' '; else first = 0; cs.str << '"' << i.ref () << '"'; } cs.str << "]\n"; }}void ElexScannerDef::outputProductions (CodeStream &cs){ cs.indent (); cs.str << "productions\n"; cs.indent (); cs.str << "[\n"; cs.incIndent (); for (Productions::Iterator i (productions); i; i++) { cs.indent (); cs.str << '"' << i.ref () << "\"\n"; } cs.decIndent (); cs.indent (); cs.str << "]\n";}void ElexScannerDef::outputStates (CodeStream &cs){ // used to map state ID's to a continuous range of numbers int *idToNumber = new int [FsmState::maxID () + 1]; // create a mapping from a production number to a production name so // that prodNumToName [i] == pointer to name of production i string **prodNumToName = new string * [productions.nItems () + 1]; Productions::Iterator p (productions); for (string **name = prodNumToName + 1; p; name++, p++) { *name = &(p.ref ()); } fsm.markReferenced (); int stateNumber = 0; Fsm::Iterator i (fsm.getStates ()); // allocate continuous state numbers for ( ; i; i++) { const FsmState &state = i.ref (); if (state.isMarked ()) { idToNumber [state.getID ()] = stateNumber++; } } // output states cs.startAttrListValue ("states"); for (i.reset (); i; i++) { FsmState &state = i.ref (); if (state.isMarked ()) { cs.indent (); cs.str << "(\n"; cs.incIndent (); cs.singleAttr ("state", idToNumber [state.getID ()]); // print edges if (state.nEdges () > 0) { cs.startAttrListValue ("edges"); for (FsmEdgeList::Iterator e (state.getEdgeList ()); e; e++) { const FsmEdge &edge = e.ref (); cs.indent (); cs.str << "(range \""; cs.printChar (edge.lower); if (edge.upper != edge.lower) { cs.str << '-'; cs.printChar (edge.upper); } cs.str << "\" "; cs.scalarAttr ("target", idToNumber [edge.getTarget ().getID ()]); cs.str << ")\n"; } // edges loop cs.endAttrListValue (); } // if state.nEdges () > 0 if (state.isFinal ()) { cs.indent (); cs.scalarAttr ("production", *(prodNumToName [state.getProd ()])); cs.str << endl; } // end state object cs.decIndent (); cs.indent (); cs.str << ")\n"; } // end isMarked (state) } cs.endAttrListValue (); delete idToNumber; delete prodNumToName;}void ElexScannerDef::outputScanner (ostream &s){ CodeStream cs (s); cs.str << "(\n"; cs.incIndent (); cs.singleAttr ("name", name); // base class (if specified) if (base.length () > 0) cs.singleAttr ("base", base); // tokens outputTokens (cs); // productions outputProductions (cs); // states outputStates (cs); // end cs.decIndent (); cs.str << ")\n";}#ifdef __GNUC__template class ClosedHashImp<int, string, DLinkedAssocItem<int, string>, ElexScannerDef::Hash, ElexScannerDef::HashSize>;template class ClosedHashImpIter<int, string, DLinkedAssocItem<int, string>, ElexScannerDef::Hash, ElexScannerDef::HashSize>;#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -