static void Main(string[] args) { Lexer lexer = new Lexer(); TokenStream strm = new TokenStream(lexer.Tokenise(Tests.test_a)); Parser parser = new Parser(); Node root; try { root = parser.Parse(strm); Console.WriteLine("It worked! {0}", root); } catch (Exception e) { Console.WriteLine(e.Message); Console.ReadKey(); return; } var behavioursModel = root.As<MapValue>()["Behaviours"].As<MapValue>(); Dictionary<string, Behaviour> behaviourDict = new Dictionary<string, Behaviour>(); Translate.Populate(behaviourDict, behavioursModel); Console.ReadKey(); }
public Model.Node Parse(TokenStream strm) { // Sanity check if (strm.EoS) { return(null); } // Initialise parse state Stack <Symbol> parseStack = new Stack <Symbol>(); parseStack.Push(Symbol.ParseState(0)); Symbol lookahead = strm.Read(); // Loop until we're done bool done = false; while (!done) { // Read current parse state Symbol parseState = parseStack.Peek(); if (!parseState.IsParseState) { throw new InvalidOperationException(); } StateDefinition state = parseStates[parseState.State]; // Select next action int terminalIndex = lookahead != null ? lookahead.TerminalIndex : SYMCNT_TERMINAL - 1; var rule = state.LookaheadTable[terminalIndex]; switch (rule.Action) { case ParserAction.Shift: parseStack.Push(lookahead); lookahead = strm.Read(); parseStack.Push(Symbol.ParseState(rule.Arg)); break; case ParserAction.Reduce: GrammarRule grammarRule = grammarRules[rule.Arg]; int toRemove = grammarRule.MatchSymbols.Length; Symbol[] children = new Symbol[toRemove]; while (toRemove > 0) { Symbol s = parseStack.Pop(); if (!s.IsParseState) { children[toRemove - 1] = s; toRemove--; } } Symbol newSymbol = new Symbol(grammarRule.OutputSymbol, children); Symbol priorState = parseStack.Peek(); if (!priorState.IsParseState) { throw new InvalidOperationException(); } StateDefinition priorStateDef = parseStates[priorState.State]; int nextState = priorStateDef.GotoTable[SymbolTypeToCol(grammarRule.OutputSymbol, true)]; parseStack.Push(newSymbol); parseStack.Push(Symbol.ParseState(nextState)); break; case ParserAction.Done: done = true; break; case ParserAction.Error: if (lookahead != null) { throw new InvalidOperationException($"Unexpected symbol '{lookahead.Value}' (line {lookahead.Position.Line}, col {lookahead.Position.Column})"); } else { throw new InvalidOperationException($"Unexpected end of stream"); } } } // Locate the parse tree Symbol parseTree = null; while (parseStack.Count > 0) { Symbol sym = parseStack.Pop(); if (!sym.IsParseState) { if (parseTree != null) { throw new InvalidOperationException($"Multiple parse trees generated (got '{sym.Type}', already had '{parseTree.Type}')"); } else { parseTree = sym; } } } if (parseTree == null) { throw new InvalidOperationException($"Parse tree not generated"); } // Identify it switch (parseTree.Type) { case SymbolType.KeyValueSeq: // We're going to emit a map var map = new Model.MapValue(); PopulateMap(map, parseTree); return(map); case SymbolType.ArraySeq: // We're going to emit an array var arr = new Model.ArrayValue(); PopulateArray(arr, parseTree); return(arr); default: throw new InvalidOperationException($"Unexpected root symbol '{parseTree.Type}'"); } }