FINALLY fixed an error that took weeks. Turned out that the ParseRule was shallow copied, and the lookahead was not copied correctly. So it got extended and thus skipped over the state when it should have been redone.
This commit is contained in:
@@ -12,7 +12,7 @@
|
|||||||
enum ASTType {undef, translation_unit, interpreter_directive, import, identifier,
|
enum ASTType {undef, translation_unit, interpreter_directive, import, identifier,
|
||||||
function, code_block,
|
function, code_block,
|
||||||
typed_parameter, expression, boolean_expression, statement,
|
typed_parameter, expression, boolean_expression, statement,
|
||||||
if_statement, return_statement, assignment_statement, declaration_statement,
|
if_statement, while_loop, for_loop, return_statement, assignment_statement, declaration_statement,
|
||||||
function_call, value};
|
function_call, value};
|
||||||
enum ValueType {none, boolean, integer, floating, double_percision, char_string };
|
enum ValueType {none, boolean, integer, floating, double_percision, char_string };
|
||||||
|
|
||||||
|
|||||||
@@ -27,30 +27,38 @@ typed_parameter_list = typed_parameter_list WS "," WS typed_parameter | typed_pa
|
|||||||
typed_parameter = type WS parameter ;
|
typed_parameter = type WS parameter ;
|
||||||
|
|
||||||
opt_parameter_list = parameter_list | ;
|
opt_parameter_list = parameter_list | ;
|
||||||
parameter_list = parameter_list WS parameter | parameter ;
|
parameter_list = parameter_list WS "," WS parameter | parameter ;
|
||||||
parameter = boolean_expression ;
|
parameter = boolean_expression ;
|
||||||
|
|
||||||
code_block = "{" WS statement_list WS "}" ;
|
if_statement = "if" WS "\(" WS boolean_expression WS "\)" WS statement ;
|
||||||
statement_list = statement_list WS statement | statement ;
|
|
||||||
statement = if_statement | return_statement | boolean_expression WS ";" | boolean_expression WS ";" | assignment_statement WS ";" | declaration_statement WS ";" | code_block ;
|
|
||||||
function_call = scope identifier "\(" WS opt_parameter_list WS "\)" ;
|
|
||||||
scope = scope identifier "::" | ;
|
|
||||||
|
|
||||||
if_statement = "if" WS boolean_expression WS statement ;
|
while_loop = "while" WS boolean_expression WS statement ;
|
||||||
|
|
||||||
|
for_update = "\(" WS statement_list WS "\)" ;
|
||||||
|
for_loop = "for" WS for_update WS statement ;
|
||||||
|
|
||||||
return_statement = "return" WS boolean_expression WS ";" ;
|
return_statement = "return" WS boolean_expression WS ";" ;
|
||||||
|
|
||||||
|
code_block = "{" WS statement_list WS "}" ;
|
||||||
|
|
||||||
|
statement_list = statement_list WS statement | statement ;
|
||||||
|
statement = if_statement | while_loop | for_loop | return_statement | boolean_expression WS ";" | assignment_statement WS ";" | declaration_statement WS ";" | code_block ;
|
||||||
|
function_call = scope identifier "\(" WS opt_parameter_list WS "\)" ;
|
||||||
|
scope = scope identifier "::" | ;
|
||||||
|
|
||||||
boolean_expression = boolean_expression WS "\|\|" WS and_boolean_expression | and_boolean_expression ;
|
boolean_expression = boolean_expression WS "\|\|" WS and_boolean_expression | and_boolean_expression ;
|
||||||
and_boolean_expression = and_boolean_expression "&&" bool_exp | bool_exp ;
|
and_boolean_expression = and_boolean_expression "&&" bool_exp | bool_exp ;
|
||||||
bool_exp = "!" WS bool_exp | expression WS comparator WS expression | bool | expression ;
|
bool_exp = "!" WS bool_exp | expression WS comparator WS expression | bool | expression ;
|
||||||
comparator = "==" | "<=" | ">=" | "!=" ;
|
comparator = "==" | "<=" | ">=" | "!=" | "<" | ">" ;
|
||||||
|
|
||||||
expression = expression WS "-" WS term | expression WS "\+" WS term | term ;
|
expression = expression WS "<<" WS term | expression WS ">>" WS shiftand | shiftand ;
|
||||||
term = term WS forward_slash WS factor | term WS "\*" WS factor | factor ;
|
shiftand = shiftand WS "-" WS term | shiftand WS "\+" WS term | term ;
|
||||||
factor = number | identifier | function_call | bool | string | "\(" WS boolean_expression WS "\)" ;
|
term = term WS forward_slash WS factor | term WS "\*" WS factor | term WS "%" WS factor | factor ;
|
||||||
|
factor = "\+\+" WS unarad | unarad WS "\+\+" | "--" WS unarad | unarad WS "--" | "\+" WS unarad | "-" WS unarad | "!" WS unarad | "~" WS unarad | "\(" WS type WS "\)" WS unarad | "\*" WS unarad | "&" WS unarad | unarad ;
|
||||||
|
unarad = number | identifier | function_call | bool | string | "\(" WS boolean_expression WS "\)" ;
|
||||||
number = integer | float | double ;
|
number = integer | float | double ;
|
||||||
|
|
||||||
assignment_statement = identifier WS "=" WS boolean_expression ;
|
assignment_statement = identifier WS "=" WS boolean_expression | identifier WS "+=" WS boolean_expression | identifier WS "-=" WS boolean_expression | identifier WS "\*=" WS boolean_expression | identifier WS "/=" WS boolean_expression ;
|
||||||
declaration_statement = type WS identifier WS "=" WS boolean_expression ;
|
declaration_statement = type WS identifier WS "=" WS boolean_expression ;
|
||||||
|
|
||||||
alphanumeric = alphanumeric numeric | alphanumeric alpha | numeric | alpha ;
|
alphanumeric = alphanumeric numeric | alphanumeric alpha | numeric | alpha ;
|
||||||
@@ -60,6 +68,6 @@ integer = sign numeric | sign hexadecimal | "null" ;
|
|||||||
float = sign numeric "." numeric "f" ;
|
float = sign numeric "." numeric "f" ;
|
||||||
double = sign numeric "." numeric | sign numeric "." numeric "d" ;
|
double = sign numeric "." numeric | sign numeric "." numeric "d" ;
|
||||||
bool = "true" | "false" | "True" | "False" ;
|
bool = "true" | "false" | "True" | "False" ;
|
||||||
alpha = "(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|.|_)+" ;
|
alpha = "(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|_)+" ;
|
||||||
numeric = "(0|1|2|3|4|5|6|7|8|9)+" ;
|
numeric = "(0|1|2|3|4|5|6|7|8|9)+" ;
|
||||||
string = "\"(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|.|!|\?|_|-| | |\\|/|\||0|1|2|3|4|5|6|7|8|9)+\"" ;
|
string = "\"(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|.|!|\?|_|-| | |\\|/|\||0|1|2|3|4|5|6|7|8|9)+\"" ;
|
||||||
2
main.cpp
2
main.cpp
@@ -88,7 +88,7 @@ int main(int argc, char* argv[]) {
|
|||||||
//std::cout << "Doing stateSetToString from Main" << std::endl;
|
//std::cout << "Doing stateSetToString from Main" << std::endl;
|
||||||
// std::cout << "\n\n\n\n\n\n\n\n\n\nState Set toString" << std::endl;
|
// std::cout << "\n\n\n\n\n\n\n\n\n\nState Set toString" << std::endl;
|
||||||
// std::cout << parser.stateSetToString() << std::endl;
|
// std::cout << parser.stateSetToString() << std::endl;
|
||||||
// std::cout << "finished stateSetToString from Main" << std::endl;
|
// std::cout << "finished stateSetToString from Main" << std::endl;
|
||||||
// std::cout << "\n\n\n\n\n\n\n\n\n\nTable" << std::endl;
|
// std::cout << "\n\n\n\n\n\n\n\n\n\nTable" << std::endl;
|
||||||
// std::cout << parser.tableToString() << std::endl;
|
// std::cout << parser.tableToString() << std::endl;
|
||||||
// std::cout << "\n\n\n\n\n\n\n\n\n\nGrammer Input File" << std::endl;
|
// std::cout << "\n\n\n\n\n\n\n\n\n\nGrammer Input File" << std::endl;
|
||||||
|
|||||||
@@ -66,52 +66,40 @@ std::string ASTData::ASTTypeToString(ASTType type) {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case translation_unit:
|
case translation_unit:
|
||||||
return "translation_unit";
|
return "translation_unit";
|
||||||
break;
|
|
||||||
case interpreter_directive:
|
case interpreter_directive:
|
||||||
return "interpreter_directive";
|
return "interpreter_directive";
|
||||||
break;
|
|
||||||
case identifier:
|
case identifier:
|
||||||
return "identifier";
|
return "identifier";
|
||||||
break;
|
|
||||||
case import:
|
case import:
|
||||||
return "import";
|
return "import";
|
||||||
break;
|
|
||||||
case function:
|
case function:
|
||||||
return "function";
|
return "function";
|
||||||
break;
|
|
||||||
case code_block:
|
case code_block:
|
||||||
return "code_block";
|
return "code_block";
|
||||||
break;
|
|
||||||
case typed_parameter:
|
case typed_parameter:
|
||||||
return "typed_parameter";
|
return "typed_parameter";
|
||||||
break;
|
|
||||||
case expression:
|
case expression:
|
||||||
return "expression";
|
return "expression";
|
||||||
break;
|
|
||||||
case boolean_expression:
|
case boolean_expression:
|
||||||
return "boolean_expression";
|
return "boolean_expression";
|
||||||
break;
|
|
||||||
case statement:
|
case statement:
|
||||||
return "statement";
|
return "statement";
|
||||||
break;
|
|
||||||
case if_statement:
|
case if_statement:
|
||||||
return "if_statement";
|
return "if_statement";
|
||||||
break;
|
case while_loop:
|
||||||
|
return "while_loop";
|
||||||
|
case for_loop:
|
||||||
|
return "for_loop";
|
||||||
case return_statement:
|
case return_statement:
|
||||||
return "return_statement";
|
return "return_statement";
|
||||||
break;
|
|
||||||
case assignment_statement:
|
case assignment_statement:
|
||||||
return "assignment_statement";
|
return "assignment_statement";
|
||||||
break;
|
|
||||||
case declaration_statement:
|
case declaration_statement:
|
||||||
return "declaration_statement";
|
return "declaration_statement";
|
||||||
break;
|
|
||||||
case function_call:
|
case function_call:
|
||||||
return "function_call";
|
return "function_call";
|
||||||
break;
|
|
||||||
case value:
|
case value:
|
||||||
return "value";
|
return "value";
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
return "unknown_ASTType";
|
return "unknown_ASTType";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,23 +61,15 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from) {
|
|||||||
} else {
|
} else {
|
||||||
return transform(children[0]); //Just a promoted bool_exp, so do child
|
return transform(children[0]); //Just a promoted bool_exp, so do child
|
||||||
}
|
}
|
||||||
} else if (name == "expression") {
|
//Here's the order of ops stuff
|
||||||
//If this is an actual part of an expression, not just a premoted term
|
} else if (name == "expression" || name == "shiftand" || name == "term" || name == "unarad") {
|
||||||
|
//If this is an actual part of an expression, not just a premoted child
|
||||||
if (children.size() > 1) {
|
if (children.size() > 1) {
|
||||||
std::string functionCallName = concatSymbolTree(children[1]);
|
std::string functionCallName = concatSymbolTree(children[1]);
|
||||||
newNode = new NodeTree<ASTData>(functionCallName, ASTData(function_call, Symbol(functionCallName, true)));
|
newNode = new NodeTree<ASTData>(functionCallName, ASTData(function_call, Symbol(functionCallName, true)));
|
||||||
skipChildren.insert(1);
|
skipChildren.insert(1);
|
||||||
} else {
|
} else {
|
||||||
return transform(children[0]); //Just a promoted term, so do child
|
return transform(children[0]); //Just a promoted child, so do it instead
|
||||||
}
|
|
||||||
} else if (name == "term") {
|
|
||||||
//If this is an actual part of an expression, not just a premoted factor
|
|
||||||
if (children.size() > 1) {
|
|
||||||
std::string functionCallName = concatSymbolTree(children[1]);
|
|
||||||
newNode = new NodeTree<ASTData>(functionCallName, ASTData(function_call, Symbol(functionCallName, true)));
|
|
||||||
skipChildren.insert(1);
|
|
||||||
} else {
|
|
||||||
return transform(children[0]); //Just a promoted factor, so do child
|
|
||||||
}
|
}
|
||||||
} else if (name == "factor") {
|
} else if (name == "factor") {
|
||||||
return transform(children[0]); //Just a premoted number or function call or something, so use it instead
|
return transform(children[0]); //Just a premoted number or function call or something, so use it instead
|
||||||
@@ -85,10 +77,28 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from) {
|
|||||||
newNode = new NodeTree<ASTData>(name, ASTData(statement));
|
newNode = new NodeTree<ASTData>(name, ASTData(statement));
|
||||||
} else if (name == "if_statement") {
|
} else if (name == "if_statement") {
|
||||||
newNode = new NodeTree<ASTData>(name, ASTData(if_statement));
|
newNode = new NodeTree<ASTData>(name, ASTData(if_statement));
|
||||||
|
} else if (name == "while_loop") {
|
||||||
|
newNode = new NodeTree<ASTData>(name, ASTData(while_loop));
|
||||||
|
} else if (name == "for_loop") {
|
||||||
|
newNode = new NodeTree<ASTData>(name, ASTData(for_loop));
|
||||||
} else if (name == "return_statement") {
|
} else if (name == "return_statement") {
|
||||||
newNode = new NodeTree<ASTData>(name, ASTData(return_statement));
|
newNode = new NodeTree<ASTData>(name, ASTData(return_statement));
|
||||||
} else if (name == "assignment_statement") {
|
} else if (name == "assignment_statement") {
|
||||||
newNode = new NodeTree<ASTData>(name, ASTData(assignment_statement));
|
newNode = new NodeTree<ASTData>(name, ASTData(assignment_statement));
|
||||||
|
std::string assignFuncName = concatSymbolTree(children[1]);
|
||||||
|
if (assignFuncName == "=") {
|
||||||
|
newNode->addChild(transform(children[0]));
|
||||||
|
newNode->addChild(transform(children[2]));
|
||||||
|
} else {
|
||||||
|
//For assignments like += or *=, expand the syntatic sugar.
|
||||||
|
NodeTree<ASTData>* lhs = transform(children[0]);
|
||||||
|
NodeTree<ASTData>* childCall = new NodeTree<ASTData>(assignFuncName, ASTData(function_call, Symbol(assignFuncName, true)));
|
||||||
|
childCall->addChild(lhs);
|
||||||
|
childCall->addChild(transform(children[2]));
|
||||||
|
newNode->addChild(lhs);
|
||||||
|
newNode->addChild(childCall);
|
||||||
|
}
|
||||||
|
return newNode;
|
||||||
} else if (name == "declaration_statement") {
|
} else if (name == "declaration_statement") {
|
||||||
newNode = new NodeTree<ASTData>(name, ASTData(declaration_statement));
|
newNode = new NodeTree<ASTData>(name, ASTData(declaration_statement));
|
||||||
NodeTree<ASTData>* newIdentifier = transform(children[1]); //Transform the identifier
|
NodeTree<ASTData>* newIdentifier = transform(children[1]); //Transform the identifier
|
||||||
|
|||||||
@@ -27,10 +27,8 @@ std::string CGenerator::generate(NodeTree<ASTData>* from) {
|
|||||||
break;
|
break;
|
||||||
case import:
|
case import:
|
||||||
return "#include <" + data.symbol.getName() + ">\n";
|
return "#include <" + data.symbol.getName() + ">\n";
|
||||||
break;
|
|
||||||
case identifier:
|
case identifier:
|
||||||
return data.symbol.getName();
|
return data.symbol.getName();
|
||||||
break;
|
|
||||||
case function:
|
case function:
|
||||||
output += "\n" + ValueTypeToCType(data.valueType) + " " + data.symbol.getName() + "(";
|
output += "\n" + ValueTypeToCType(data.valueType) + " " + data.symbol.getName() + "(";
|
||||||
for (int i = 0; i < children.size()-1; i++) {
|
for (int i = 0; i < children.size()-1; i++) {
|
||||||
@@ -40,7 +38,6 @@ std::string CGenerator::generate(NodeTree<ASTData>* from) {
|
|||||||
}
|
}
|
||||||
output+= ")\n" + generate(children[children.size()-1]);
|
output+= ")\n" + generate(children[children.size()-1]);
|
||||||
return output;
|
return output;
|
||||||
break;
|
|
||||||
case code_block:
|
case code_block:
|
||||||
output += "{\n";
|
output += "{\n";
|
||||||
tabLevel++;
|
tabLevel++;
|
||||||
@@ -49,22 +46,23 @@ std::string CGenerator::generate(NodeTree<ASTData>* from) {
|
|||||||
tabLevel--;
|
tabLevel--;
|
||||||
output += tabs() + "}";
|
output += tabs() + "}";
|
||||||
return output;
|
return output;
|
||||||
break;
|
|
||||||
case expression:
|
case expression:
|
||||||
output += " " + data.symbol.getName() + ", ";
|
output += " " + data.symbol.getName() + ", ";
|
||||||
break;
|
|
||||||
case boolean_expression:
|
case boolean_expression:
|
||||||
output += " " + data.symbol.getName() + " ";
|
output += " " + data.symbol.getName() + " ";
|
||||||
break;
|
|
||||||
case statement:
|
case statement:
|
||||||
return tabs() + generate(children[0]) + ";\n";
|
return tabs() + generate(children[0]) + ";\n";
|
||||||
break;
|
|
||||||
case if_statement:
|
case if_statement:
|
||||||
output += "if (" + generate(children[0]) + ")\n\t" + generate(children[1]);
|
output += "if (" + generate(children[0]) + ")\n\t" + generate(children[1]);
|
||||||
if (children.size() > 2)
|
if (children.size() > 2)
|
||||||
output += " else " + generate(children[2]);
|
output += " else " + generate(children[2]);
|
||||||
return output;
|
return output;
|
||||||
break;
|
case while_loop:
|
||||||
|
output += "if (" + generate(children[0]) + ")\n\t" + generate(children[1]);
|
||||||
|
return output;
|
||||||
|
case for_loop:
|
||||||
|
output += "if (" + generate(children[0]) + ")\n\t" + generate(children[1]);
|
||||||
|
return output;
|
||||||
case return_statement:
|
case return_statement:
|
||||||
return "return " + generate(children[0]);
|
return "return " + generate(children[0]);
|
||||||
case assignment_statement:
|
case assignment_statement:
|
||||||
@@ -76,7 +74,7 @@ std::string CGenerator::generate(NodeTree<ASTData>* from) {
|
|||||||
//Handle operators specially for now. Will later replace with
|
//Handle operators specially for now. Will later replace with
|
||||||
//Inlined functions in the standard library
|
//Inlined functions in the standard library
|
||||||
std::string name = data.symbol.getName();
|
std::string name = data.symbol.getName();
|
||||||
if (name == "+" || name == "-" || name == "*" || name == "/" || name == "==" || name == ">=" || name == "<=" || name == "!=") {
|
if (name == "+" || name == "-" || name == "*" || name == "/" || name == "==" || name == ">=" || name == "<=" || name == "!=" || name == "%") {
|
||||||
return "((" + generate(children[0]) + ")" + name + "(" + generate(children[1]) + "))";
|
return "((" + generate(children[0]) + ")" + name + "(" + generate(children[1]) + "))";
|
||||||
}
|
}
|
||||||
output += data.symbol.getName() + "(";
|
output += data.symbol.getName() + "(";
|
||||||
|
|||||||
@@ -29,7 +29,12 @@ const bool ParseRule::operator!=(const ParseRule &other) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ParseRule* ParseRule::clone() {
|
ParseRule* ParseRule::clone() {
|
||||||
return( new ParseRule(leftHandle, pointerIndex, rightSide, lookahead) );
|
std::vector<Symbol>* newLookahead = NULL;
|
||||||
|
if (lookahead) {
|
||||||
|
newLookahead = new std::vector<Symbol>();
|
||||||
|
*newLookahead = *lookahead;
|
||||||
|
}
|
||||||
|
return( new ParseRule(leftHandle, pointerIndex, rightSide, newLookahead) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParseRule::setLeftHandle(Symbol leftHandle) {
|
void ParseRule::setLeftHandle(Symbol leftHandle) {
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ void Parser::createStateSet() {
|
|||||||
std::queue<State*>* toDo = new std::queue<State*>();
|
std::queue<State*>* toDo = new std::queue<State*>();
|
||||||
toDo->push(zeroState);
|
toDo->push(zeroState);
|
||||||
//std::cout << "Begining for main set for loop" << std::endl;
|
//std::cout << "Begining for main set for loop" << std::endl;
|
||||||
while (toDo->front()) {
|
while (toDo->size()) {
|
||||||
//closure
|
//closure
|
||||||
closure(toDo->front());
|
closure(toDo->front());
|
||||||
//Add the new states
|
//Add the new states
|
||||||
@@ -181,7 +181,7 @@ std::vector<Symbol>* Parser::incrementiveFollowSet(ParseRule* rule) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
followSet->insert(followSet->end(), symbolFirstSet->begin(), symbolFirstSet->end());
|
followSet->insert(followSet->end(), symbolFirstSet->begin(), symbolFirstSet->end());
|
||||||
//delete symbolFirstSet;
|
delete symbolFirstSet;
|
||||||
rule->advancePointer();
|
rule->advancePointer();
|
||||||
}
|
}
|
||||||
if (rule->isAtEnd()) {
|
if (rule->isAtEnd()) {
|
||||||
@@ -209,10 +209,13 @@ void Parser::closure(State* state) {
|
|||||||
std::vector<ParseRule*>* stateTotal = state->getTotal();
|
std::vector<ParseRule*>* stateTotal = state->getTotal();
|
||||||
for (std::vector<ParseRule*>::size_type i = 0; i < stateTotal->size(); i++) {
|
for (std::vector<ParseRule*>::size_type i = 0; i < stateTotal->size(); i++) {
|
||||||
ParseRule* currentStateRule = (*stateTotal)[i];
|
ParseRule* currentStateRule = (*stateTotal)[i];
|
||||||
|
//If it's at it's end, move on. We can't advance it.
|
||||||
|
if(currentStateRule->isAtEnd())
|
||||||
|
continue;
|
||||||
for (std::vector<ParseRule*>::size_type j = 0; j < loadedGrammer.size(); j++) {
|
for (std::vector<ParseRule*>::size_type j = 0; j < loadedGrammer.size(); j++) {
|
||||||
//If the current symbol in the rule is not null (rule completed) and it equals a grammer's left side
|
//If the current symbol in the rule is not null (rule completed) and it equals a grammer's left side
|
||||||
ParseRule* currentGramRule = loadedGrammer[j]->clone();
|
ParseRule* currentGramRule = loadedGrammer[j]->clone();
|
||||||
if ( !currentStateRule->isAtEnd() && currentStateRule->getAtNextIndex() == currentGramRule->getLeftSide()) {
|
if (currentStateRule->getAtNextIndex() == currentGramRule->getLeftSide()) {
|
||||||
//std::cout << (*stateTotal)[i]->getAtNextIndex()->toString() << " has an applicable production " << loadedGrammer[j]->toString() << std::endl;
|
//std::cout << (*stateTotal)[i]->getAtNextIndex()->toString() << " has an applicable production " << loadedGrammer[j]->toString() << std::endl;
|
||||||
//Now, add the correct lookahead. This followSet is built based on the current rule's lookahead if at end, or the next Symbol's first set.
|
//Now, add the correct lookahead. This followSet is built based on the current rule's lookahead if at end, or the next Symbol's first set.
|
||||||
//std::cout << "Setting lookahead for " << currentGramRule->toString() << " in state " << state->toString() << std::endl;
|
//std::cout << "Setting lookahead for " << currentGramRule->toString() << " in state " << state->toString() << std::endl;
|
||||||
@@ -225,6 +228,7 @@ void Parser::closure(State* state) {
|
|||||||
//std::cout << (*stateTotal)[k]->toString() << std::endl;
|
//std::cout << (*stateTotal)[k]->toString() << std::endl;
|
||||||
(*stateTotal)[k]->addLookahead(currentGramRule->getLookahead());
|
(*stateTotal)[k]->addLookahead(currentGramRule->getLookahead());
|
||||||
isAlreadyInState = true;
|
isAlreadyInState = true;
|
||||||
|
delete currentGramRule;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -311,7 +315,7 @@ void Parser::addStates(std::vector< State* >* stateSets, State* state, std::queu
|
|||||||
std::string Parser::stateSetToString() {
|
std::string Parser::stateSetToString() {
|
||||||
std::string concat = "";
|
std::string concat = "";
|
||||||
for (std::vector< State *>::size_type i = 0; i < stateSets.size(); i++) {
|
for (std::vector< State *>::size_type i = 0; i < stateSets.size(); i++) {
|
||||||
concat += stateSets[i]->toString();
|
concat += intToString(i) + " is " + stateSets[i]->toString();
|
||||||
}
|
}
|
||||||
return concat;
|
return concat;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,10 @@ NodeTree<Symbol>* RNGLRParser::parseInput(std::string inputString) {
|
|||||||
std::cout << "Nearby is:" << std::endl;
|
std::cout << "Nearby is:" << std::endl;
|
||||||
int range = 5;
|
int range = 5;
|
||||||
for (int j = (i-range >= 0 ? i-range : 0); j < (i+range < input.size() ? i+range : input.size()); j++)
|
for (int j = (i-range >= 0 ? i-range : 0); j < (i+range < input.size() ? i+range : input.size()); j++)
|
||||||
std::cout << input[j].toString() << " ";
|
if (j == i)
|
||||||
|
std::cout << "||*||*||" << input[j].toString() << "||*||*|| ";
|
||||||
|
else
|
||||||
|
std::cout << input[j].toString() << " ";
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -339,11 +342,13 @@ void RNGLRParser::addStates(std::vector< State* >* stateSets, State* state, std:
|
|||||||
//if (newStates[i]->basisEquals(*((*stateSets)[j]))) {
|
//if (newStates[i]->basisEquals(*((*stateSets)[j]))) {
|
||||||
stateAlreadyInAllStates = true;
|
stateAlreadyInAllStates = true;
|
||||||
//If it does exist, we should add it as the shift/goto in the action table
|
//If it does exist, we should add it as the shift/goto in the action table
|
||||||
|
//std::cout << "newStates[" << i << "] == stateSets[" << j << "]" << std::endl;
|
||||||
|
|
||||||
if (!((*stateSets)[j]->basisEquals(*(newStates[i]))))
|
if (!((*stateSets)[j]->basisEquals(*(newStates[i]))))
|
||||||
toDo->push((*stateSets)[j]);
|
toDo->push((*stateSets)[j]);
|
||||||
|
|
||||||
(*stateSets)[j]->combineStates(*(newStates[i]));
|
(*stateSets)[j]->combineStates(*(newStates[i]));
|
||||||
|
//std::cout << j << "\t Hay, doing an inside loop state reductions!" << std::endl;
|
||||||
addStateReductionsToTable((*stateSets)[j]);
|
addStateReductionsToTable((*stateSets)[j]);
|
||||||
table.add(stateNum(state), currStateSymbol, new ParseAction(ParseAction::SHIFT, j));
|
table.add(stateNum(state), currStateSymbol, new ParseAction(ParseAction::SHIFT, j));
|
||||||
|
|
||||||
@@ -368,8 +373,9 @@ void RNGLRParser::addStateReductionsToTable(State* state) {
|
|||||||
//Also, this really only needs to be done for the state's basis, but we're already iterating through, so...
|
//Also, this really only needs to be done for the state's basis, but we're already iterating through, so...
|
||||||
std::vector<Symbol>* lookahead = (*currStateTotal)[i]->getLookahead();
|
std::vector<Symbol>* lookahead = (*currStateTotal)[i]->getLookahead();
|
||||||
if ((*currStateTotal)[i]->isAtEnd()) {
|
if ((*currStateTotal)[i]->isAtEnd()) {
|
||||||
for (std::vector<Symbol>::size_type j = 0; j < lookahead->size(); j++)
|
for (std::vector<Symbol>::size_type j = 0; j < lookahead->size(); j++) {
|
||||||
table.add(stateNum(state), (*lookahead)[j], new ParseAction(ParseAction::REDUCE, (*currStateTotal)[i]));
|
table.add(stateNum(state), (*lookahead)[j], new ParseAction(ParseAction::REDUCE, (*currStateTotal)[i]));
|
||||||
|
}
|
||||||
//If this has an appropriate ruduction to null, get the reduce trees out
|
//If this has an appropriate ruduction to null, get the reduce trees out
|
||||||
} else if (reducesToNull((*currStateTotal)[i])) {
|
} else if (reducesToNull((*currStateTotal)[i])) {
|
||||||
//std::cout << (*currStateTotal)[i]->toString() << " REDUCES TO NULL" << std::endl;
|
//std::cout << (*currStateTotal)[i]->toString() << " REDUCES TO NULL" << std::endl;
|
||||||
|
|||||||
@@ -79,12 +79,9 @@ void State::combineStates(State &other) {
|
|||||||
|
|
||||||
std::vector<ParseRule*>* State::getTotal() {
|
std::vector<ParseRule*>* State::getTotal() {
|
||||||
total.clear();
|
total.clear();
|
||||||
for (std::vector<ParseRule*>::size_type i = 0; i < basis.size(); i++) {
|
//std::cout << "Vector will be " << basis.size() << " + " << remaining.size() << std::endl;
|
||||||
total.push_back(basis[i]);
|
total.insert(total.begin(), basis.begin(), basis.end());
|
||||||
}
|
total.insert(total.end(), remaining.begin(), remaining.end());
|
||||||
for (std::vector<ParseRule*>::size_type i = 0; i < remaining.size(); i++) {
|
|
||||||
total.push_back(remaining[i]);
|
|
||||||
}
|
|
||||||
return(&total);
|
return(&total);
|
||||||
}
|
}
|
||||||
std::vector<ParseRule*>* State::getBasis() {
|
std::vector<ParseRule*>* State::getBasis() {
|
||||||
@@ -111,6 +108,7 @@ void State::addRuleCombineLookahead(ParseRule* rule) {
|
|||||||
if (rule->equalsExceptLookahead(*(total[i]))) {
|
if (rule->equalsExceptLookahead(*(total[i]))) {
|
||||||
total[i]->addLookahead(rule->getLookahead());
|
total[i]->addLookahead(rule->getLookahead());
|
||||||
alreadyIn = true;
|
alreadyIn = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!alreadyIn)
|
if (!alreadyIn)
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ std::vector<ParseAction*>* Table::get(int state, Symbol token) {
|
|||||||
action->push_back(new ParseAction(ParseAction::ACCEPT));
|
action->push_back(new ParseAction(ParseAction::ACCEPT));
|
||||||
}
|
}
|
||||||
|
|
||||||
//If ourside the symbol range of this state (same as NULL), reject
|
//If outside the symbol range of this state (same as NULL), reject
|
||||||
if ( symbolIndex >= table[state]->size() ) {
|
if ( symbolIndex >= table[state]->size() ) {
|
||||||
action = new std::vector<ParseAction*>();
|
action = new std::vector<ParseAction*>();
|
||||||
action->push_back(new ParseAction(ParseAction::REJECT));
|
action->push_back(new ParseAction(ParseAction::REJECT));
|
||||||
@@ -141,7 +141,7 @@ std::vector<ParseAction*>* Table::get(int state, Symbol token) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Otherwise, we have something, so return it
|
//Otherwise, we have something, so return it
|
||||||
return (action);
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseAction* Table::getShift(int state, Symbol token) {
|
ParseAction* Table::getShift(int state, Symbol token) {
|
||||||
@@ -163,8 +163,9 @@ std::string Table::toString() {
|
|||||||
concat += "\n";
|
concat += "\n";
|
||||||
|
|
||||||
for (std::vector< std::vector< std::vector< ParseRule* >* >* >::size_type i = 0; i < table.size(); i++) {
|
for (std::vector< std::vector< std::vector< ParseRule* >* >* >::size_type i = 0; i < table.size(); i++) {
|
||||||
concat += intToString(i) + "\t";
|
concat += intToString(i) + " is the state\t";
|
||||||
for (std::vector< std::vector< ParseRule* >* >::size_type j = 0; j < table[i]->size(); j++) {
|
for (std::vector< std::vector< ParseRule* >* >::size_type j = 0; j < table[i]->size(); j++) {
|
||||||
|
concat += "for " + symbolIndexVec[j].toString() + " do ";
|
||||||
if ( (*(table[i]))[j] != NULL) {
|
if ( (*(table[i]))[j] != NULL) {
|
||||||
for (std::vector< ParseRule* >::size_type k = 0; k < (*(table[i]))[j]->size(); k++) {
|
for (std::vector< ParseRule* >::size_type k = 0; k < (*(table[i]))[j]->size(); k++) {
|
||||||
concat += (*((*(table[i]))[j]))[k]->toString() + "\t";
|
concat += (*((*(table[i]))[j]))[k]->toString() + "\t";
|
||||||
|
|||||||
Reference in New Issue
Block a user