From dec9b7d0bdba33eec1d47a0edf8f072a5642baf2 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Wed, 5 Aug 2015 03:43:34 -0400 Subject: [PATCH] some tests failing because things have been made reference in vector, but grammer actually generates the state set for the real grammer in 2 minutes or so after a day of profiling and bugfixing, so this is gonna be committed. --- krakenGrammer.kgm | 2 +- src/CGenerator.cpp | 2 +- src/Parser.cpp | 4 + stdlib/grammer.krak | 121 +++++++++++++++---------- stdlib/set.krak | 3 + stdlib/stack.krak | 43 +++++++++ stdlib/vector.krak | 16 ++-- tests/grammer2.kgm | 4 +- tests/test_grammer.krak | 4 +- tests/test_set.expected_results | 3 + tests/test_set.krak | 2 + tests/test_vectorTest.expected_results | 2 + tests/test_vectorTest.krak | 5 + 13 files changed, 151 insertions(+), 60 deletions(-) create mode 100644 stdlib/stack.krak diff --git a/krakenGrammer.kgm b/krakenGrammer.kgm index 4981c6b..65fa857 100644 --- a/krakenGrammer.kgm +++ b/krakenGrammer.kgm @@ -61,7 +61,7 @@ identifier = augmented_alpha_alphanumeric ; scope_op = ":" ":" ; scoped_identifier = scoped_identifier WS scope_op WS identifier | identifier ; -#Note that to prevent confilct with nested templates (T>) it is a nonterminal contructed as follows +#Note that to prevent confilct with nested templates (T>) right_shift is a nonterminal contructed as follows right_shift = ">" ">" ; overloadable_operator = "\+" | "-" | "\*" | "/" | "%" | "^" | "&" | "\|" | "~" | "!" | "," | "=" | "\+\+" | "--" | "<<" | right_shift | "==" | "!=" | "&&" | "\|\|" | "\+=" | "-=" | "/=" | "%=" | "^=" | "&=" | "\|=" | "\*=" | "<<=" | ">>=" | "->" | "\(" "\)" | "[]" | "[]=" ; func_identifier = identifier | identifier overloadable_operator ; diff --git a/src/CGenerator.cpp b/src/CGenerator.cpp index 1938c0e..9825551 100644 --- a/src/CGenerator.cpp +++ b/src/CGenerator.cpp @@ -13,7 +13,7 @@ CGenerator::~CGenerator() { // Note the use of std::pair to hold two strings - the running string for the header file and the running string for the c file. void CGenerator::generateCompSet(std::map*> ASTs, std::string outputName) { //Generate an entire set of files - std::string buildString = "#!/bin/sh\ncc -g -std=c99 "; + std::string buildString = "#!/bin/sh\ncc -g -O3 -std=c99 "; std::cout << "\n\n =====GENERATE PASS===== \n\n" << std::endl; std::cout << "\n\nGenerate pass for: " << outputName << std::endl; buildString += outputName + ".c "; diff --git a/src/Parser.cpp b/src/Parser.cpp index 42440b0..2298b17 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -112,7 +112,11 @@ void Parser::createStateSet() { std::queue toDo; toDo.push(zeroState); //std::cout << "Begining for main set for loop" << std::endl; + int count = 0; while (toDo.size()) { + if (count % 200 == 0) + std::cout << "while count: " << count << std::endl; + count++; //closure closure(toDo.front()); //Add the new states diff --git a/stdlib/grammer.krak b/stdlib/grammer.krak index bc59e06..9df9887 100644 --- a/stdlib/grammer.krak +++ b/stdlib/grammer.krak @@ -1,6 +1,7 @@ import string import vector import set +import stack import map import symbol import regex @@ -176,90 +177,112 @@ obj grammer (Object) { fun calculate_state_automaton() { state_automata.items = vector::vector(rules[0].with_lookahead(set::set(symbol::eof_symbol()))) + io::println("pre first closure") state_automata = closure(state_automata) - var states = set::set(state_automata) - var newItem = true - while (newItem) { - newItem = false - states.for_each(fun(I: state) { - var possGoto = set::set() - I.items.for_each(fun(r: rule) { - if (!r.at_end()) - possGoto.add(r.next()) - }) - possGoto.for_each(fun(X: symbol::symbol) { - var goneState = goto(I, X) - if (goneState.items.size && !states.contains(goneState)) { - states.add(goneState) - newItem = true - } - }) + io::println("post first closure") + var states = vector::vector(state_automata) // vector instead of set because we need to iterate by index + var newItems = stack::stack(0) // 0 is the index of the first and only item in states + var count = 0 + while (newItems.size()) { + if (count%200 == 0) { + io::print("calculate_state_automaton while") + io::println(count) + } + count++ + var I = newItems.pop() + var possGoto = set::set() + states[I].items.for_each(fun(r: ref rule) { + if (!r.at_end()) + possGoto.add(r.next()) + }) + possGoto.for_each(fun(X: ref symbol::symbol) { + var goneState = goto(states[I], X) + if (goneState.items.size && !states.contains(goneState)) { + newItems.push(states.size) + states.add(goneState) + } }) } io::println("ALL STATES:\n") - states.for_each(fun(i: state) { + states.for_each(fun(i: ref state) { io::println("STATE:\n") - i.items.for_each(fun(r: rule) { + i.items.for_each(fun(r: ref rule) { io::println(string::string("\t") + r.to_string()) }) }) + io::println(" there were : states") + io::println(states.size) } - fun closure(initial: state): state { + fun closure(initial: ref state): state { initial.items = closure(initial.items) return initial } - fun closure(initial: vector::vector): vector::vector { + fun closure(initial: ref vector::vector): vector::vector { var continueIt = true - var count = 0 + //var count = 0 while (continueIt) { - io::print("while") - io::println(count) - count++ + //io::print("closure while") + //io::println(count) + //count++ continueIt = false - initial.for_each(fun(i: rule) { - if (i.at_end()) { - return; // continue the for-each + for (var i = 0; i < initial.size; i++;) { + if (initial[i].at_end()) { + continue } - rules.for_each(fun(r: rule) { + rules.for_each(fun(r: ref rule) { // if i is |a::=c . Bb, a|, we're doing each B::=... in rules - if (r.lhs != i.next()) - return // continuing rule-for_each + if (r.lhs != initial[i].next()) + return // continue the for-each // add r with lookahead - var newLookahead = first_vector(i.after_next()) + var newLookahead = first_vector(initial[i].after_next()) if (newLookahead.contains(symbol::null_symbol())) { newLookahead.remove(symbol::null_symbol()) - newLookahead.add(i.lookahead) + newLookahead.add(initial[i].lookahead) } + var alreadyInInSomeForm = false for (var index = 0; index < initial.size; index++;) { - if (initial[index].equals_but_lookahead(r) && !initial[index].lookahead.contains(newLookahead)) { - //io::println(initial[index].to_string()) - //io::println("and") - //io::println(r.to_string()) - //io::println("are the same with different lookaheads") - initial[index].lookahead += newLookahead - continueIt = true - //io::println("contineu because equal_but_different") - return // continuing rule-for_each + if (initial[index].equals_but_lookahead(r)) { + alreadyInInSomeForm = true + if (!initial[index].lookahead.contains(newLookahead)) { + //io::println("\n\n\n") + //io::println(initial[index].to_string()) + //io::println("and") + //io::println(r.to_string()) + //io::println("with") + //var result = string::string("|lookahead {") + //newLookahead.for_each(fun(i: symbol::symbol) { + //result += i.to_string() + //}) + //io::println(result) + //io::println("are the same with different lookaheads") + initial[index].lookahead += newLookahead + //io::println("so now it's") + //io::println(initial[index].to_string()) + //io::println("contineu because equal_but_different") + continueIt = true + return // continue the rules for-each + } } } - var newRule = r.with_lookahead(newLookahead) - if (!initial.contains(newRule)) { + if (!alreadyInInSomeForm) { continueIt = true + //io::println("\n\n\n") //io::println("contineu because not contains") - initial.add(newRule) + //io::println(newRule.to_string()) + initial.add(r.with_lookahead(newLookahead)) } }) - }) + } } return initial } - fun goto(I: state, X: symbol::symbol): state { + fun goto(I: ref state, X: ref symbol::symbol): state { // loop through i, find all that have thing::= something . X more, // add thing ::= something X . more var jPrime = vector::vector() - I.items.for_each(fun(i: rule) { + I.items.for_each(fun(i: ref rule) { if (!i.at_end() && i.next() == X) jPrime.add(i.advanced()) }) @@ -323,7 +346,7 @@ obj rule (Object) { lookahead.destruct() } - fun next(): symbol::symbol { + fun next(): ref symbol::symbol { return rhs[position] } fun after_next(): vector::vector { diff --git a/stdlib/set.krak b/stdlib/set.krak index 08848f5..e8d7b71 100644 --- a/stdlib/set.krak +++ b/stdlib/set.krak @@ -71,6 +71,9 @@ obj set (Object) { } data.remove(idx) } + fun for_each(func: fun(ref T):void) { + data.for_each(func) + } fun for_each(func: fun(T):void) { data.for_each(func) } diff --git a/stdlib/stack.krak b/stdlib/stack.krak new file mode 100644 index 0000000..d3ebe83 --- /dev/null +++ b/stdlib/stack.krak @@ -0,0 +1,43 @@ +import vector + + +fun stack():stack { + var out.construct():stack + return out +} +fun stack(in:T):stack { + var out.construct():stack + out.push(in) + return out +} + +obj stack (Object) { + var data: vector::vector + fun construct(): *stack { + data.construct() + return this + } + fun copy_construct(other: *stack) { + data.copy_construct(&other->data) + } + fun destruct() { + data.destruct() + } + fun operator=(other: ref stack) { + data = other.data + } + fun push(it: ref T) { + data.addEnd(it) + } + fun pop(): T { + var toRet = data[data.size-1] + data.remove(data.size-1) + return toRet + } + fun top(): T { + return data[data.size-1] + } + fun size(): int { + return data.size + } +} diff --git a/stdlib/vector.krak b/stdlib/vector.krak index d555ff6..1e67b2a 100644 --- a/stdlib/vector.krak +++ b/stdlib/vector.krak @@ -121,19 +121,19 @@ obj vector (Object) { // on an object that we want to put in a vector. In this way we avoid the problem // by not generating this function unless it's called - we also get the ability to // do a find index using a different type, which could be fun. - fun find(value: U): int { + fun find(value: ref U): int { for (var i = 0; i < size; i++;) if (data[i] == value) return i; return -1; } // ditto - fun contains(item: U): bool { + fun contains(item: ref U): bool { return find(item) != -1 } // yep - fun operator==(other:vector):bool { + fun operator==(other: ref vector):bool { if (size != other.size) return false for (var i = 0; i < size; i++;) @@ -147,7 +147,7 @@ obj vector (Object) { return; data[index] = dataIn; } - fun add_all(dataIn: vector): void { + fun add_all(dataIn: ref vector): void { for (var i = 0; i < dataIn.size; i++;) addEnd(dataIn[i]); } @@ -156,8 +156,8 @@ obj vector (Object) { if (!contains(dataIn)) addEnd(dataIn) } - fun add(dataIn: T): void { addEnd(dataIn); } - fun addEnd(dataIn: T): void { + fun add(dataIn: ref T): void { addEnd(dataIn); } + fun addEnd(dataIn: ref T): void { if (size+1 >= available) resize((size+1)*2); maybe_copy_construct(&data[size], &dataIn); @@ -173,6 +173,10 @@ obj vector (Object) { size-- } + fun for_each(func: fun(ref T):void):void { + for (var i = 0; i < size; i++;) + func(data[i]) + } fun for_each(func: fun(T):void):void { for (var i = 0; i < size; i++;) func(data[i]) diff --git a/tests/grammer2.kgm b/tests/grammer2.kgm index f82266a..b9ea6fd 100644 --- a/tests/grammer2.kgm +++ b/tests/grammer2.kgm @@ -1,5 +1,6 @@ # comment -a = b ; +Goal = a ; +a = b | rec ; b = "c":named_c ; b = c "d":dname ; c = "a" | d ; @@ -9,3 +10,4 @@ e = f | ; f = ; post_null = "hi" ; post_non_null = "bye" ; +rec = "hmm" rec | ; diff --git a/tests/test_grammer.krak b/tests/test_grammer.krak index f923118..3b528fd 100644 --- a/tests/test_grammer.krak +++ b/tests/test_grammer.krak @@ -7,9 +7,9 @@ import symbol:* fun main():int { - //var a = load_grammer(read_file(string("../krakenGrammer.kgm"))) + var a = load_grammer(read_file(string("../krakenGrammer.kgm"))) /*var a = load_grammer(read_file(string("grammer.kgm")))*/ - var a = load_grammer(read_file(string("grammer2.kgm"))) + //var a = load_grammer(read_file(string("grammer2.kgm"))) println(a.to_string()) var doFirstSet = fun() { a.calculate_first_set() diff --git a/tests/test_set.expected_results b/tests/test_set.expected_results index 7844457..9f1ec33 100644 --- a/tests/test_set.expected_results +++ b/tests/test_set.expected_results @@ -16,3 +16,6 @@ true all: 4 5 +all ref: +4 +5 diff --git a/tests/test_set.krak b/tests/test_set.krak index 01f56fa..b069cb9 100644 --- a/tests/test_set.krak +++ b/tests/test_set.krak @@ -27,5 +27,7 @@ fun main():int { println("all:") s.for_each( fun(it: int) println(it); ) + println("all ref:") + s.for_each( fun(it: ref int) println(it); ) return 0 } diff --git a/tests/test_vectorTest.expected_results b/tests/test_vectorTest.expected_results index 5de4c83..5ff0300 100644 --- a/tests/test_vectorTest.expected_results +++ b/tests/test_vectorTest.expected_results @@ -6,6 +6,8 @@ 15513 3.7000007.7000007.70000015.700000 123456789101112 +with references +123456789101112 Constructed: 0 Copied: 0 to 1 Copied: 1 to 2 diff --git a/tests/test_vectorTest.krak b/tests/test_vectorTest.krak index 7bc1934..9f825a3 100644 --- a/tests/test_vectorTest.krak +++ b/tests/test_vectorTest.krak @@ -69,6 +69,11 @@ fun main(): int { vector(1,2,3,4,5,6,7,8,9,10,11,12).for_each(fun(i:int) { print(i); }) println() + // with references + println("with references") + vector(1,2,3,4,5,6,7,8,9,10,11,12).for_each(fun(i: ref int) { print(i); }) + println() + var desVec: *vector = new>()->construct(); var testDestruct.construct(0): AbleToBeDestroyed; desVec->addEnd(testDestruct);