Added caching of the RNGLR table. It is automatically regenerated whenever the grammer changes. Right now it has dropped compiling the test file from 30 seconds to less than one second.
This commit is contained in:
197
src/Table.cpp
197
src/Table.cpp
@@ -8,6 +8,203 @@ Table::~Table() {
|
||||
//
|
||||
}
|
||||
|
||||
void Table::exportTable(std::ofstream &file) {
|
||||
//Save symbolIndexVec
|
||||
int size = symbolIndexVec.size();
|
||||
file.write((char*)&size, sizeof(int));
|
||||
for (int i = 0; i < symbolIndexVec.size(); i++) {
|
||||
//Save the name
|
||||
std::string symbolName = symbolIndexVec[i].getName(); //Get the string
|
||||
size = symbolName.size()+1;
|
||||
file.write((char*)&size, sizeof(int)); //Save size of string
|
||||
file.write((char*)(symbolName.c_str()), size); //Save the string
|
||||
|
||||
//Save the value
|
||||
std::string symbolValue = symbolIndexVec[i].getValue(); //Get the string
|
||||
size = symbolValue.size()+1;
|
||||
file.write((char*)&size, sizeof(int)); //Save size of string
|
||||
file.write((char*)(symbolValue.c_str()), size); //Save the string
|
||||
|
||||
bool isTerminal = symbolIndexVec[i].isTerminal();
|
||||
file.write((char*)&isTerminal, sizeof(bool)); //Save the true false
|
||||
}
|
||||
|
||||
//Save the actual table
|
||||
size = table.size();
|
||||
file.write((char*)&size, sizeof(int));
|
||||
for (int i = 0; i < table.size(); i++) {
|
||||
//each item is a middle vector
|
||||
//std::vector< std::vector< std::vector<ParseAction*>* >* > table;
|
||||
std::vector< std::vector<ParseAction*>* >* middleVector = table[i];
|
||||
int middleVectorSize = middleVector->size();
|
||||
file.write((char*)&middleVectorSize, sizeof(int));
|
||||
|
||||
for (int j = 0; j < middleVectorSize; j++) {
|
||||
//each item is an inner vector
|
||||
std::vector<ParseAction*>* innerVector = (*middleVector)[j];
|
||||
int innerVectorSize = 0;
|
||||
if (innerVector)
|
||||
innerVectorSize = innerVector->size();
|
||||
else
|
||||
innerVectorSize = 0;
|
||||
file.write((char*)&innerVectorSize, sizeof(int));
|
||||
|
||||
for (int k = 0; k < innerVectorSize; k++) {
|
||||
//Save the type
|
||||
ParseAction* toSave = (*innerVector)[k];
|
||||
ParseAction::ActionType actionType = toSave->action;
|
||||
file.write((char*)&actionType, sizeof(ParseAction::ActionType));
|
||||
//Save the reduce rule if necessary
|
||||
if (actionType == ParseAction::REDUCE) {
|
||||
//Save the reduce rule
|
||||
ParseRule* rule = toSave->reduceRule;
|
||||
//int pointer index
|
||||
int ptrIndx = rule->getIndex();
|
||||
file.write((char*)&ptrIndx, sizeof(int));
|
||||
|
||||
//Symbol leftHandle
|
||||
Symbol leftHandle = rule->getLeftSide();
|
||||
//Save the name
|
||||
std::string symbolName = leftHandle.getName(); //Get the string
|
||||
size = symbolName.size()+1;
|
||||
file.write((char*)&size, sizeof(int)); //Save size of string
|
||||
file.write((char*)(symbolName.c_str()), size); //Save the string
|
||||
|
||||
//Save the value
|
||||
std::string symbolValue = leftHandle.getValue(); //Get the string
|
||||
size = symbolValue.size()+1;
|
||||
file.write((char*)&size, sizeof(int)); //Save size of string
|
||||
file.write((char*)(symbolValue.c_str()), size); //Save the string
|
||||
|
||||
bool isTerminal = leftHandle.isTerminal();
|
||||
file.write((char*)&isTerminal, sizeof(bool)); //Save the true false
|
||||
|
||||
//std::vector<Symbol>* lookahead;
|
||||
//Should not need
|
||||
|
||||
//std::vector<Symbol> rightSide;
|
||||
std::vector<Symbol> rightSide = rule->getRightSide();
|
||||
size = rightSide.size();
|
||||
std::cout << leftHandle.toString() << std::endl;
|
||||
file.write((char*)&size, sizeof(int));
|
||||
for (int l = 0; l < rightSide.size(); l++) {
|
||||
//Save the name
|
||||
symbolName = rightSide[l].getName(); //Get the string
|
||||
size = symbolName.size()+1;
|
||||
file.write((char*)&size, sizeof(int)); //Save size of string
|
||||
file.write((char*)(symbolName.c_str()), size); //Save the string
|
||||
//
|
||||
//Save the value
|
||||
symbolValue = rightSide[l].getValue(); //Get the string
|
||||
size = symbolValue.size()+1;
|
||||
file.write((char*)&size, sizeof(int)); //Save size of string
|
||||
file.write((char*)(symbolValue.c_str()), size); //Save the string
|
||||
//
|
||||
isTerminal = rightSide[l].isTerminal();
|
||||
file.write((char*)&isTerminal, sizeof(bool)); //Save the true false
|
||||
}
|
||||
}
|
||||
int shiftState = toSave->shiftState;
|
||||
file.write((char*)&shiftState, sizeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Table::importTable(char* tableData) {
|
||||
//Load symbolIndexVec
|
||||
|
||||
int size = *((int*)tableData);
|
||||
tableData += sizeof(int);
|
||||
for (int i = 0; i < size; i++) {
|
||||
int stringLen = *((int*)tableData);
|
||||
tableData += sizeof(int);
|
||||
std::string symbolName = std::string(tableData);
|
||||
tableData += stringLen*sizeof(char);
|
||||
stringLen = *((int*)tableData);
|
||||
tableData += sizeof(int);
|
||||
std::string symbolValue = std::string(tableData);
|
||||
tableData += stringLen*sizeof(char);
|
||||
|
||||
bool isTerminal = *((bool*)tableData);
|
||||
tableData += sizeof(bool);
|
||||
|
||||
symbolIndexVec.push_back(Symbol(symbolName, isTerminal, symbolValue));
|
||||
}
|
||||
|
||||
//Now for the actual table
|
||||
int tableSize = *((int*)tableData);
|
||||
tableData += sizeof(int);
|
||||
for (int i = 0; i < tableSize; i++) {
|
||||
//each item is a middle vector
|
||||
std::vector< std::vector<ParseAction*>* >* middleVector = new std::vector< std::vector<ParseAction*>* >();
|
||||
table.push_back(middleVector);
|
||||
|
||||
int middleVectorSize = *((int*)tableData);
|
||||
tableData += sizeof(int);
|
||||
for (int j = 0; j < middleVectorSize; j++) {
|
||||
//each item is an inner vector
|
||||
std::vector<ParseAction*>* innerVector = new std::vector<ParseAction*>();
|
||||
middleVector->push_back(innerVector);
|
||||
int innerVectorSize = *((int*)tableData);
|
||||
tableData += sizeof(int);
|
||||
for (int k = 0; k < innerVectorSize; k++) {
|
||||
//each item is a ParseRule
|
||||
ParseAction::ActionType action = *((ParseAction::ActionType*)tableData);
|
||||
tableData += sizeof(ParseAction::ActionType);
|
||||
//If reduce, import the reduce rule
|
||||
ParseRule* reduceRule = NULL;
|
||||
if (action == ParseAction::REDUCE) {
|
||||
int ptrIndx = *((int*)tableData);
|
||||
tableData += sizeof(int);
|
||||
|
||||
size = *((int*)tableData);
|
||||
tableData += sizeof(int);
|
||||
std::string leftHandleName = std::string(tableData);
|
||||
tableData += size*sizeof(char);
|
||||
size = *((int*)tableData);
|
||||
tableData += sizeof(int);
|
||||
std::string leftHandleValue = std::string(tableData);
|
||||
tableData += size*sizeof(char);
|
||||
|
||||
bool isTerminal = *((bool*)tableData);
|
||||
tableData += sizeof(bool);
|
||||
|
||||
//right side
|
||||
std::vector<Symbol> rightSide;
|
||||
size = *((int*)tableData);
|
||||
tableData += sizeof(int);
|
||||
for (int l = 0; l < size; l++) {
|
||||
int inStringLen = *((int*)tableData);
|
||||
tableData += sizeof(int);
|
||||
std::string inSymbolName = std::string(tableData);
|
||||
tableData += inStringLen*sizeof(char);
|
||||
|
||||
inStringLen = *((int*)tableData);
|
||||
tableData += sizeof(int);
|
||||
std::string inSymbolValue = std::string(tableData);
|
||||
tableData += inStringLen*sizeof(char);
|
||||
|
||||
bool inIsTerminal = *((bool*)tableData);
|
||||
tableData += sizeof(bool);
|
||||
rightSide.push_back(Symbol(inSymbolName, inIsTerminal, inSymbolValue));
|
||||
}
|
||||
reduceRule = new ParseRule(Symbol(leftHandleName, isTerminal, leftHandleValue), ptrIndx, rightSide, NULL);
|
||||
}
|
||||
int shiftState = *((int*)tableData);
|
||||
tableData += sizeof(int);
|
||||
|
||||
//And push the new action back
|
||||
if (reduceRule)
|
||||
innerVector->push_back(new ParseAction(action, reduceRule));
|
||||
else
|
||||
innerVector->push_back(new ParseAction(action, shiftState));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Table::setSymbols(Symbol EOFSymbol, Symbol nullSymbol) {
|
||||
this->EOFSymbol = EOFSymbol;
|
||||
this->nullSymbol = nullSymbol;
|
||||
|
||||
Reference in New Issue
Block a user