📄 dynamicscanner.cpp
字号:
/* $Id: DynamicScanner.cpp,v 1.5 1997/02/02 01:31:03 matt Exp $ Elex dynamic scanner class. (c) Matt Phillips 1996. */#include "DynamicScanner.h"// the production number for the dynamic scanner's error production.enum {ErrorProduction = -100};DynamicScanner::DynamicScanner (const FooObject &scandef, XInputStream &i) : ElexScanner (scannerData, i){ generate (scandef); state = scannerData.start;}DynamicScanner::~DynamicScanner (){ delete [] prodNames; for (int c = 0; c < nStates; c++) { ElexState *state = states + c; if (state->edges) { delete state->edges->edges; delete state->edges; } }}// Generates the corresponding ElexEdge structure for fooedges.ElexEdge *DynamicScanner::generateEdges (const FooObject::Objects &fooedges, ElexState *states) const{ ElexEdge *edges = new ElexEdge [fooedges.nItems ()]; ElexEdge *edge = edges; for (FooObject::Objects::Iterator e (fooedges); e; e++, edge++) { const string &range = e.ref ().getAttrString ("range"); edge->target = states + e.ref ().getAttrInt ("target"); edge->lower = range [0]; if (range.length () == 3) edge->upper = range [2]; else edge->upper = range [0]; } return edges;}// Generates the states and edges structures that correspond to the// scanner FSM defined in scandef. Fills in the scannerData.start and// nStates variables.// NOTE: the while loop below used to be a for loop, but for some// reason this caused an internal compiler error under g++ 2.7.2. In// fact, putting _anything_ after the loop seems to hose the compiler.// Modify this function carefully!void DynamicScanner::generate (const FooObject &scandef){ const FooObject::Objects &foostates = scandef.getAttrs ("states"); nStates = foostates.nItems (); // allocate storage for states and state ID -> production name // mapping. states = new ElexState [nStates]; prodNames = new string [nStates]; scannerData.start = states; scannerData.errorProd = ErrorProduction; // for each state... FooObject::Objects::Iterator s (foostates); while (s) { int stateNo = s.ref ().getAttrInt ("state"); ElexState *state = states + stateNo; const FooObject::Objects &fooedges = s.ref ().getAttrs ("edges"); if (fooedges.nItems () > 0) { // allocate and generate edges for state. state->edges = new ElexEdges; state->edges->nEdges = fooedges.nItems (); state->edges->edges = generateEdges (fooedges, states); } else state->edges = 0; // fill in the production name for state. const string &prodName = s.ref ().getAttrString ("production"); prodNames [stateNo] = prodName; state->prod = prodName.length () > 0 ? stateNo : ElexState::NoProduction; s++; }}int DynamicScanner::invokeProduction (int i){ if (i == ErrorProduction) production = "<Error>"; else production = prodNames [i]; return i;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -