diff --git a/stdlib/grammer.krak b/stdlib/grammer.krak index 5470999..ec7db21 100644 --- a/stdlib/grammer.krak +++ b/stdlib/grammer.krak @@ -175,17 +175,56 @@ obj grammer (Object) { } fun calculate_state_automaton() { + state_automata.kernel = vector::vector(rules[0].with_lookahead(set::set(symbol::eof_symbol()))) + 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(); // needed to disambiguate next line + (I.kernel + I.rest).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.kernel.size && !states.contains(goneState)) { + states.add(goneState) + newItem = true + } + }) + }) + } + io::println("ALL STATES:\n") + states.for_each(fun(i: state) { + io::println("STATE:\n") + io::println("\tKERNEL:\n") + i.kernel.for_each(fun(r: rule) { + io::println(string::string("\t\t") + r.to_string()) + }) + io::println("\tREST:\n") + i.rest.for_each(fun(r: rule) { + io::println(string::string("\t\t") + r.to_string()) + }) + }) } + fun closure(initial: state): state { + initial.rest = closure(initial.kernel) + return initial + } fun closure(initial: vector::vector): vector::vector { var continueIt = true while (continueIt) { continueIt = false initial.for_each(fun(i: rule) { + if (i.at_end()) + return; // continue the for-each rules.for_each(fun(r: rule) { // if i is |a::=c . Bb, a|, we're doing each B::=... in rules if (r.lhs != i.next()) - return + return // continuing rule-for_each // add r with lookahead var newLookahead = first_vector(r.after_next()) if (newLookahead.contains(symbol::null_symbol())) { @@ -196,7 +235,7 @@ obj grammer (Object) { if (initial[index].equals_but_lookahead(r)) { initial[index].lookahead += newLookahead continueIt = true - return; // continuing rule-for_each + return // continuing rule-for_each } } var newRule = r.with_lookahead(newLookahead) @@ -210,6 +249,18 @@ obj grammer (Object) { return initial } + fun goto(I: state, X: symbol::symbol): state { + // loop through i, find all that have thing::= something . X more, + // add thing ::= something X . more + var jPrime = vector::vector(); // ; needed to disambiguate next line + (I.kernel + I.rest).for_each(fun(i: rule) { + if (i.next() == X) + jPrime.add(i.advanced()) + }) + // return closure(that)? + return state(jPrime, closure(jPrime)) + } + fun to_string(): string::string { var result = string::string("grammer rules:") rules.for_each( fun(i : rule) { result += string::string("\n\t") + i.to_string(); } ) @@ -252,8 +303,7 @@ obj rule (Object) { destruct() copy_construct(&other) } - //fun operator==(other: ref rule):bool { - fun operator==(other: rule):bool { + fun operator==(other: ref rule):bool { return lhs == other.lhs && rhs == other.rhs && position == other.position && lookahead == other.lookahead } @@ -273,20 +323,38 @@ obj rule (Object) { fun after_next(): vector::vector { return rhs.slice(position + 1, -1) } + fun at_end(): bool { + return position < rhs.size + } fun with_lookahead(newLookahead: set::set): rule { var toRet = rule(lhs, rhs) toRet.position = position toRet.lookahead = newLookahead return toRet } + fun advanced(): rule { + var toRet = rule(lhs, rhs) + toRet.position = position+1 + toRet.lookahead = lookahead + return toRet + } fun to_string(): string::string { var result = lhs.name + " -> " - rhs.for_each( fun(i : symbol::symbol) { result += i.to_string() + ", "; } ) + for (var i = 0; i < rhs.size; i++;) + if (i == position) + result += string::string(" . ") + rhs[i].to_string() + ", "; + else + result += rhs[i].to_string() + ", "; return result } } +fun state(kernelIn: ref vector::vector, restIn: ref vector::vector): state { + var toRet.construct(kernelIn, restIn): state + return toRet +} + obj state (Object) { var kernel: vector::vector var rest: vector::vector @@ -311,6 +379,9 @@ obj state (Object) { kernel.destruct() rest.destruct() } + fun operator==(other: ref state):bool { + return kernel == other.kernel && rest == other.rest + } fun to_string(): string::string { return string::string("woo a state") } diff --git a/stdlib/symbol.krak b/stdlib/symbol.krak index 2a47a86..3006ead 100644 --- a/stdlib/symbol.krak +++ b/stdlib/symbol.krak @@ -1,7 +1,11 @@ import string fun null_symbol(): symbol { - var toRet.construct(string::string("$NULL"), false, string::string("$NULL$")): symbol + var toRet.construct(string::string("$NULL$"), false, string::string("$NULL$")): symbol + return toRet +} +fun eof_symbol(): symbol { + var toRet.construct(string::string("$EOF$"), false, string::string("$EOF$")): symbol return toRet } diff --git a/tests/test_access_expression.expected_results b/tests/test_access_expression.expected_results new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/tests/test_access_expression.expected_results @@ -0,0 +1 @@ +1 diff --git a/tests/test_access_expression.krak b/tests/test_access_expression.krak new file mode 100644 index 0000000..7a03fd7 --- /dev/null +++ b/tests/test_access_expression.krak @@ -0,0 +1,23 @@ +import io:* +import vector:* + +obj container { + var v1: vector + var v2: vector + fun construct(): *container { + v1.construct() + v2.construct() + } + fun destruct() { + v1.destruct() + v2.destruct() + } +} + +fun main():int { + var c.construct() : container + c.v1 = vector(1); // need this ; otherwise this could ambigiously be one or two lines + (c.v1).for_each(fun(i: int) { + println(i) + }) +} diff --git a/tests/test_grammer.krak b/tests/test_grammer.krak index 908fc41..17bdd55 100644 --- a/tests/test_grammer.krak +++ b/tests/test_grammer.krak @@ -47,6 +47,7 @@ fun main():int { range(8).for_each(fun(i: int) { println(lex.next().to_string()); } ) /*range(80).for_each(fun(i: int) { println(lex.next().to_string()); } )*/ println(a.to_string()) + a.calculate_state_automaton() return 0 }