Basic structures work, prep work for function pointers and other stuff,a couple of bugs fixed.

This commit is contained in:
Nathan Braswell
2014-01-19 18:20:52 -05:00
parent b59fd26d4a
commit 62933af8f8
12 changed files with 95 additions and 25 deletions

View File

@@ -33,6 +33,7 @@ class State {
void addParents(std::vector<State*>* parents);
std::vector<State*>* getParents();
std::vector<State*>* getDeepParents(int depth);
int getNumber();
std::vector<ParseRule*> basis;

View File

@@ -8,10 +8,13 @@
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
std::string intToString(int theInt);
std::string replaceExEscape(std::string first, std::string search, std::string replace);
std::string strSlice(std::string str, int begin, int end);
int findPerenEnd(std::string str, int i);
std::vector<std::string> split(const std::string &str, char delim);
std::string join(const std::vector<std::string> &strVec, std::string joinStr);
#endif

View File

@@ -56,8 +56,7 @@ code_block = "{" WS statement_list WS "}" ;
statement_list = statement_list WS statement | statement ;
statement = if_statement | while_loop | for_loop | return_statement WS ";" | boolean_expression WS ";" | assignment_statement WS ";" | declaration_statement WS ";" | code_block | if_comp | simple_passthrough ;
function_call = scope identifier "\(" WS opt_parameter_list WS "\)" ;
scope = scope identifier "::" | ;
function_call = unarad "\(" WS opt_parameter_list WS "\)" ;
boolean_expression = boolean_expression WS "\|\|" WS and_boolean_expression | and_boolean_expression ;
and_boolean_expression = and_boolean_expression "&&" bool_exp | bool_exp ;
@@ -68,10 +67,11 @@ expression = expression WS "<<" WS term | expression WS ">>" WS shiftand | shift
shiftand = shiftand WS "-" WS term | shiftand WS "\+" WS term | term ;
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 | character | "\(" WS boolean_expression WS "\)" ;
unarad = number | identifier | function_call | bool | string | character | "\(" WS boolean_expression WS "\)" | access_operation ;
number = integer | float | double ;
access_operation = expression "." identifier | expression "->" identifier ;
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 ;
assignment_statement = factor WS "=" WS boolean_expression | factor WS "\+=" WS boolean_expression | factor WS "-=" WS boolean_expression | factor WS "\*=" WS boolean_expression | factor WS "/=" WS boolean_expression ;
declaration_statement = type WS identifier WS "=" WS boolean_expression | type WS identifier ;
alphanumeric = alphanumeric numeric | alphanumeric alpha | numeric | alpha ;

View File

@@ -104,14 +104,15 @@ int main(int argc, char* argv[]) {
compiledGrammerOutFile.open(grammerFileString + ".comp", std::ios::binary);
if (!compiledGrammerOutFile.is_open())
std::cout << "Could not open compiled file to write either!" << std::endl;
compiledGrammerOutFile.write("KRAK", sizeof(char)*4);
compiledGrammerOutFile.write("KRAK", sizeof(char)*4); //Let us know when we load it that this is a kraken grammer file, but don't write out
compiledGrammerOutFile.flush(); // the grammer txt until we create the set, so that if we fail creating it it won't look valid
parser.createStateSet();
int* intBuffer = new int;
*intBuffer = grammerInputFileString.length()+1;
compiledGrammerOutFile.write((char*)intBuffer, sizeof(int));
delete intBuffer;
compiledGrammerOutFile.write(grammerInputFileString.c_str(), grammerInputFileString.length()+1); //Don't forget null terminator
parser.createStateSet();
parser.exportTable(compiledGrammerOutFile);
compiledGrammerOutFile.close();
}

View File

@@ -42,6 +42,8 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
scope->getDataRef()->scope["*="] = new NodeTree<ASTData>();
scope->getDataRef()->scope["+="] = new NodeTree<ASTData>();
scope->getDataRef()->scope["-="] = new NodeTree<ASTData>();
scope->getDataRef()->scope["."] = new NodeTree<ASTData>();
scope->getDataRef()->scope["->"] = new NodeTree<ASTData>();
} else if (name == "interpreter_directive") {
newNode = new NodeTree<ASTData>(name, ASTData(interpreter_directive));
@@ -56,19 +58,31 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
scope->getDataRef()->scope[i->first] = i->second;
return newNode; // Don't need children of import
} else if (name == "identifier") {
std::string lookupName = concatSymbolTree(children[0]);
//Make sure we get the entire name
std::string lookupName = concatSymbolTree(from);
//std::cout << "scope lookup from identifier" << std::endl;
newNode = scopeLookup(scope, lookupName);
if (newNode == NULL) {
std::cout << "scope lookup error! Could not find " << lookupName << std::endl;
throw "LOOKUP ERROR: " + lookupName;
} else if (newNode->getDataRef()->symbol.getName() !=lookupName) {
//This happens when the lookup name denotes a member of an object, i.e. obj.foo
//The newNode points to obj, not foo.
}
//newNode = new NodeTree<ASTData>(name, ASTData(identifier, Symbol(concatSymbolTree(children[0]), true)));
} else if (name == "type_def") {
std::string typeAlias = concatSymbolTree(children[0]);
newNode = new NodeTree<ASTData>(name, ASTData(type_def, Symbol(typeAlias, true, typeAlias), typeFromString(concatSymbolTree(children[1]), scope)));
//If it is an alisis of a type
if (children[1]->getData().getName() == "type") {
newNode = new NodeTree<ASTData>(name, ASTData(type_def, Symbol(typeAlias, true, typeAlias), typeFromString(concatSymbolTree(children[1]), scope)));
skipChildren.insert(1); //Don't want any children, it's unnecessary for ailising
} else { //Is a struct or class
newNode = new NodeTree<ASTData>(name, ASTData(type_def, Symbol(typeAlias, true, typeAlias)));
newNode->getDataRef()->valueType = new Type(newNode); //Type is self-referential since this is the definition
}
scope->getDataRef()->scope[typeAlias] = newNode;
return newNode;
skipChildren.insert(0); //Identifier lookup will be ourselves, as we just added ourselves to the scope
//return newNode;
} else if (name == "function") {
std::string functionName = concatSymbolTree(children[1]);
newNode = new NodeTree<ASTData>(name, ASTData(function, Symbol(functionName, true), typeFromString(concatSymbolTree(children[0]), scope)));
@@ -108,7 +122,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
return transform(children[0], scope); //Just a promoted term, so do child
}
//Here's the order of ops stuff
} else if (name == "expression" || name == "shiftand" || name == "term" || name == "unarad") { //unarad can ride through, it should always just be a promoted child
} else if (name == "expression" || name == "shiftand" || name == "term" || name == "unarad" || name == "access_operation") { //unarad can ride through, it should always just be a promoted child
//If this is an actual part of an expression, not just a premoted child
if (children.size() > 2) {
std::string functionCallName = concatSymbolTree(children[1]);
@@ -187,8 +201,18 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
// newIdentifier->getDataRef()->valueType = Type(concatSymbolTree(children[0]));//set the type of the identifier
std::string newIdentifierStr = concatSymbolTree(children[1]);
std::string typeString = concatSymbolTree(children[0]);//Get the type (left child) and set our new identifer to be that type
NodeTree<ASTData>* newIdentifier = new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(newIdentifierStr, true), typeFromString(typeString, scope)));
Type* identifierType = typeFromString(typeString, scope);
NodeTree<ASTData>* newIdentifier = new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(newIdentifierStr, true), identifierType));
scope->getDataRef()->scope[newIdentifierStr] = newIdentifier;
//Now we don't do this thing
// if (identifierType->typeDefinition) {
// //Is a custom type. Populate this declaration's scope with it's inner declarations
// std::vector<NodeTree<ASTData>*> definitions = identifierType->typeDefinition->getChildren();
// for (auto i : definitions) {
// //Point to the identifier. May need to change so it points to the declaration or something, with new declarations.....
// newIdentifier->getDataRef()->scope[i->get(0)->getDataRef()->symbol.getName()] = i->get(0); //make each declaration's name point to it's definition, like above
// }
// }
newNode->addChild(newIdentifier);
skipChildren.insert(0); //These, the type and the identifier, have been taken care of.
@@ -200,8 +224,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
} else if (name == "simple_passthrough") {
newNode = new NodeTree<ASTData>(name, ASTData(simple_passthrough));
} else if (name == "function_call") {
//children[0] is scope
std::string functionCallName = concatSymbolTree(children[1]);
std::string functionCallName = concatSymbolTree(children[0]);
newNode = new NodeTree<ASTData>(functionCallName, ASTData(function_call, Symbol(functionCallName, true)));
//std::cout << "scope lookup from function_call" << std::endl;
NodeTree<ASTData>* function = scopeLookup(scope, functionCallName);
@@ -210,7 +233,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
throw "LOOKUP ERROR: " + functionCallName;
}
newNode->addChild(function);
skipChildren.insert(1);
skipChildren.insert(0);
} else if (name == "parameter") {
return transform(children[0], scope); //Don't need a parameter node, just the value
} else if (name == "parameter") {
@@ -261,12 +284,18 @@ std::string ASTTransformation::concatSymbolTree(NodeTree<Symbol>* root) {
}
NodeTree<ASTData>* ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std::string lookup) {
//Seach the map
//First, if it is a struct or object, get it's base.
std::vector<std::string> splitString = split(lookup, '.');
if (splitString.size() > 1) {
std::string base = splitString[0];
// NodeTree<ASTData>* baseDef = scopeLookup(scope, base);
// splitString.erase(splitString.begin()); //Get rid of the base in the split str
// //Now the base is the scope.
// return scopeLookup(baseDef, join(splitString, ".")); //So the joined version doesn't have the base.
return scopeLookup(scope, base);
}
//Search the map
auto scopeMap = scope->getDataRef()->scope;
//std::cout << "scope size: " << scopeMap.size() << ", scope from " << scope->getName() << std::endl;
// for (auto i = scopeMap.begin(); i != scopeMap.end(); i++)
// std::cout << i->first << " : " << i-> second << " - " << i->second->getName() << std::endl;
auto elementIterator = scopeMap.find(lookup);
if (elementIterator != scopeMap.end()) {
// std::cout << "lookup of " << lookup << " succeded in first scope!" << std::endl;
@@ -280,6 +309,7 @@ NodeTree<ASTData>* ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std:
return scopeLookup(enclosingIterator->second, lookup);
}
//std::cout << "upper scope does not exist" << std::endl;
std::cout << "could not find " << lookup << std::endl;
return NULL;
}

View File

@@ -87,7 +87,15 @@ std::string CGenerator::generate(NodeTree<ASTData>* from) {
case identifier:
return data.symbol.getName();
case type_def:
return "typedef " + ValueTypeToCType(data.valueType) + " " + data.symbol.getName() + ";";
if (children.size() == 0) {
return "typedef " + ValueTypeToCType(data.valueType) + " " + data.symbol.getName() + ";";
} else {
std::string objectString = "typedef struct __struct_dummy_" + data.symbol.getName() + "__ {\n";
for (int i = 0; i < children.size(); i++)
objectString += generate(children[i]) + "\n";
objectString += "} " + data.symbol.getName() + ";";
return objectString;
}
case function:
output += "\n" + ValueTypeToCType(data.valueType) + " " + data.symbol.getName() + "(";
for (int i = 0; i < children.size()-1; i++) {
@@ -155,10 +163,10 @@ std::string CGenerator::generate(NodeTree<ASTData>* from) {
return "*(" + generate(children[1]) + ")";
if (name == "+" || name == "-" || name == "*" || name == "/" || name == "==" || name == ">=" || name == "<=" || name == "!="
|| name == "<" || name == ">" || name == "%" || name == "+=" || name == "-=" || name == "*=" || name == "/=" || name == "||"
|| name == "&&" || name == "!" ) {
|| name == "&&" || name == "!" )
return "((" + generate(children[1]) + ")" + name + "(" + generate(children[2]) + "))";
}
else if (name == "." || name == "->")
return "((" + generate(children[1]) + ")" + name + generate(children[2]) + ")";
output += data.symbol.getName() + "(";
for (int i = 1; i < children.size(); i++) //children[0] is the declaration
if (i < children.size()-1)

View File

@@ -30,6 +30,7 @@ Importer::Importer(Parser* parserIn) {
collapseSymbols.push_back(Symbol("typed_parameter_list", false));
collapseSymbols.push_back(Symbol("unorderd_list_part", false));
collapseSymbols.push_back(Symbol("if_comp_pred", false));
collapseSymbols.push_back(Symbol("declaration_block", false));
}
Importer::~Importer() {

View File

@@ -377,6 +377,7 @@ void RNGLRParser::addStates(std::vector< State* >* stateSets, State* state, std:
void RNGLRParser::addStateReductionsToTable(State* state) {
std::vector<ParseRule*>* currStateTotal = state->getTotal();
//std::cout << currStateTotal->size() << "::" << state->getNumber() << std::endl;
for (std::vector<ParseRule*>::size_type i = 0; i < currStateTotal->size(); i++) {
//See if reduce
//Also, this really only needs to be done for the state's basis, but we're already iterating through, so...

View File

@@ -223,8 +223,7 @@ void RegEx::test() {
}
{
RegEx re("bbb((bba+)|(ba+))*a*((a+b)|(a+bb)|(a+))*bbb") ;
std::cout << re.longMatch("bbbababbbaaaaaaaaaaaaaaaaaaabbb") << std::endl;
assert(re.longMatch("bbbababbbaaaaaaaaaaaaaaaaaaabbb") == 9);
}
std::cout << "RegEx tests pass\n";

View File

@@ -158,4 +158,8 @@ std::vector<State*>* State::getDeepParents(int depth) {
recursiveParents->insert(recursiveParents->end(), recursiveParentsToAdd->begin(), recursiveParentsToAdd->end());
}
return recursiveParents;
}
int State::getNumber() {
return number;
}

View File

@@ -3,16 +3,19 @@
Type::Type() {
indirection = 0;
baseType = none;
typeDefinition = NULL;
}
Type::Type(ValueType typeIn) {
indirection = 0;
baseType = typeIn;
typeDefinition = NULL;
}
Type::Type(ValueType typeIn, int indirectionIn) {
indirection = indirectionIn;
baseType = typeIn;
typeDefinition = NULL;
}
Type::Type(NodeTree<ASTData>* typeDefinitionIn) {

View File

@@ -52,3 +52,22 @@ int findPerenEnd(std::string str, int i) {
return i;
}
}
std::vector<std::string> split(const std::string &str, char delim) {
std::stringstream ss(str);
std::string word;
std::vector<std::string> splitVec;
while (std::getline(ss, word, delim))
splitVec.push_back(word);
return splitVec;
}
std::string join(const std::vector<std::string> &strVec, std::string joinStr) {
if (strVec.size() == 0)
return "";
std::string joinedStr = strVec[0];
for (int i = 1; i < strVec.size(); i++)
joinedStr += joinStr + strVec[i];
return joinedStr;
}