Null rules work in RNGLR now, but there seems to be a bug where somehow some states/rules get no lookahead.

This commit is contained in:
Nathan Braswell
2013-08-02 15:21:42 -04:00
parent 49d149bc1f
commit d5b33efb22
5 changed files with 54 additions and 14 deletions

View File

@@ -33,8 +33,6 @@ class ParseRule {
int getRightSize();
int getIndex();
std::vector<NodeTree<Symbol*>*>* nullReductions();
bool advancePointer();
bool isAtEnd();

View File

@@ -11,6 +11,8 @@ class RNGLRParser: public Parser {
void reducer(int i);
void shifter(int i);
void addStates(std::vector< State* >* stateSets, State* state);
bool reducesToNull(ParseRule* rule);
bool reducesToNull(ParseRule* rule, std::vector<Symbol*> avoidList);
private:
std::vector<Symbol*> input;
GraphStructuredStack gss;

View File

@@ -23,9 +23,9 @@ void Lexer::addRegEx(std::string regExString) {
}
Symbol* Lexer::next() {
std::cout << "Current at is \"" << input.substr(currentPosition,input.length()-1) << "\" currentPos is " << currentPosition <<std::endl;
std::cout << "Current at is \"" << input.substr(currentPosition,input.length()-1) << "\" currentPos is " << currentPosition << " out of " << input.length() <<std::endl;
//If we're at the end, return an eof
if (currentPosition == input.length()-1)
if (currentPosition >= input.length()-1)
return new Symbol("$EOF$", true);
int longestMatch = -1;
RegEx* longestRegEx = NULL;
@@ -44,7 +44,7 @@ Symbol* Lexer::next() {
return new Symbol(longestRegEx->getPattern(), true);
} else {
std::cout << "Found no applicable regex" << std::endl;
std::cout << "Remaining is " << input.substr(currentPosition,input.length()-1) << std::endl;
return new Symbol("$NO_APPLICABLE_REGEX$", true);
std::cout << "Remaining is ||" << input.substr(currentPosition,input.length()-1) << "||" << std::endl;
return NULL;
}
}

View File

@@ -73,10 +73,6 @@ int ParseRule::getIndex() {
return pointerIndex;
}
std::vector<NodeTree<Symbol*>*>* ParseRule::nullReductions() {
//Return a vector of null reduction trees
}
bool ParseRule::advancePointer() {
if (pointerIndex < rightSide.size()) {
pointerIndex++;

View File

@@ -33,7 +33,12 @@ NodeTree<Symbol*>* RNGLRParser::parseInput(std::string inputString) {
while (*currentToken != *EOFSymbol) {
std::cout << EOFSymbol->toString() << " " << currentToken->toString() << std::endl;
currentToken = lexer.next();
input.push_back(currentToken);
if (currentToken != NULL) {
input.push_back(currentToken);
} else {
std::cout << "Rejected, lexer unable to fully tokenize sentence" << std::endl;
return new NodeTree<Symbol*>();
}
}
std::cout << "\n\n\nDone with Lexing\n\n\n" << std::endl;
@@ -210,8 +215,8 @@ void RNGLRParser::addStates(std::vector< State* >* stateSets, State* state) {
table.add(stateNum(state), (*lookahead)[j], new ParseAction(ParseAction::REDUCE, (*currStateTotal)[i]));
// } else if (*((*currStateTotal)[i]->getAtNextIndex()) == *nullSymbol) {
//If this has an appropriate ruduction to null, get the reduce trees out
} else if (std::vector<NodeTree<Symbol*>*>* reduceTrees = (*currStateTotal)[i]->nullReductions(), reduceTrees) {
std::cout << "REDUCE TREES" << std::endl;
} else if (reducesToNull((*currStateTotal)[i])) {
std::cout << (*currStateTotal)[i]->toString() << " REDUCES TO NULL" << std::endl;
//If is a rule that produces only NULL, add in the approprite reduction, but use a new rule with a right side of length 0. (so we don't pop off stack)
ParseRule* nullRule = (*currStateTotal)[i]->clone();
nullRule->setRightSide(* new std::vector<Symbol*>());
@@ -240,4 +245,43 @@ void RNGLRParser::addStates(std::vector< State* >* stateSets, State* state) {
table.add(stateNum(state), currStateSymbol, new ParseAction(ParseAction::SHIFT, stateSets->size()-1));
}
}
}
}
bool RNGLRParser::reducesToNull(ParseRule* rule) {
std::vector<Symbol*> avoidList;
return reducesToNull(rule, avoidList);
}
bool RNGLRParser::reducesToNull(ParseRule* rule, std::vector<Symbol*> avoidList) {
for (std::vector<Symbol*>::size_type i = 0; i < avoidList.size(); i++)
if (*(rule->getLeftSide()) == *(avoidList[i]))
return false;
avoidList.push_back(rule->getLeftSide());
std::vector<Symbol*> rightSide = rule->getRightSide();
bool reduces = true;
for (std::vector<Symbol*>::size_type i = 0; i < rightSide.size(); i++) {
if (*rightSide[i] == *nullSymbol)
continue;
if (rightSide[i]->isTerminal()) {
reduces = false;
break;
}
bool subSymbolReduces = false;
for (std::vector<ParseRule*>::size_type j = 0; j < loadedGrammer.size(); j++) {
if (*(loadedGrammer[j]->getLeftSide()) == *(rightSide[i])) {
if(reducesToNull(loadedGrammer[j], avoidList)) {
subSymbolReduces = true;
break;
}
}
}
if (!subSymbolReduces) {
reduces = false;
break;
}
}
return reduces;
}