/// <summary> /// Exports the given DFA to a DOT graph in the specified file /// </summary> /// <param name="dfa">The DFA to export</param> /// <param name="file">DOT file to export to</param> public static void ExportDOT(DFA dfa, string file) { DOTSerializer serializer = new DOTSerializer("DFA", file); foreach (DFAState state in dfa.States) { if (state.IsFinal) { ROList <FinalItem> items = state.Items; StringBuilder builder = new StringBuilder(state.ID.ToString()); builder.Append(" : "); for (int i = 0; i != items.Count; i++) { if (i != 0) { builder.Append(", "); } builder.Append(items[i].ToString()); } serializer.WriteNode("state" + state.ID, builder.ToString(), DOTNodeShape.doubleoctagon); } else { serializer.WriteNode("state" + state.ID, state.ID.ToString()); } } foreach (DFAState state in dfa.States) { foreach (CharSpan value in state.Transitions) { serializer.WriteEdge("state" + state.ID, "state" + state.GetChildBy(value).ID, value.ToString()); } } serializer.Close(); }
/// <summary> /// Initializes this code generator /// </summary> /// <param name="unit">The unit to generate code for</param> /// <param name="nmespace">The nmespace of the generated code</param> /// <param name="binResource">Path to the automaton's binary resource</param> public ParserRustCodeGenerator(Unit unit, string nmespace, string binResource) { this.nmespace = nmespace; this.name = unit.Name; this.binResource = binResource; this.grammar = unit.Grammar; if (unit.Method == ParsingMethod.RNGLR1 || unit.Method == ParsingMethod.RNGLALR1) { this.parserType = "RNGLRParser"; this.automatonType = "RNGLRAutomaton"; } else { this.parserType = "LRkParser"; this.automatonType = "LRkAutomaton"; } this.outputAssembly = unit.CompilationMode == Mode.Assembly || unit.CompilationMode == Mode.SourceAndAssembly; terminals = unit.Expected; variables = new List <Variable>(unit.Grammar.Variables); virtuals = new List <Virtual>(unit.Grammar.Virtuals); actions = new List <Action>(unit.Grammar.Actions); variables.Sort(new Grammars.Symbol.IdComparer <Variable>()); virtuals.Sort(new Grammars.Symbol.IdComparer <Virtual>()); actions.Sort(new Grammars.Symbol.IdComparer <Action>()); }
/// <summary> /// Export the content of the given LR state to the specified writer /// </summary> /// <param name="writer">The writer to export with</param> /// <param name="state">The LR state to export</param> /// <param name="grammar">The associated grammar</param> private static void ExportLRState(TextWriter writer, Hime.SDK.Grammars.LR.State state, Grammar grammar) { writer.WriteLine(); writer.WriteLine("State {0}:", state.ID); writer.WriteLine("\tContexts:"); foreach (Hime.SDK.Grammars.Symbol symbol in state.Transitions) { Terminal terminal = symbol as Terminal; if (terminal != null) { ROList <int> contexts = state.GetContextsOpenedBy(terminal); foreach (int context in contexts) { writer.WriteLine("\t\tOn {0} opening context {1}: {2}", terminal, context, grammar.GetContextName(context)); } } } writer.WriteLine("\tTransitions:"); foreach (Hime.SDK.Grammars.Symbol symbol in state.Transitions) { writer.WriteLine("\t\tOn {0} shift to {1}", symbol, state.GetChildBy(symbol).ID); } writer.WriteLine("\tItems:"); foreach (Item item in state.Items) { writer.WriteLine("\t\t" + item.ToString(true)); } writer.WriteLine("\tConflicts:"); foreach (Conflict conflict in state.Conflicts) { ExportLRConflict(writer, conflict); } }
/// <summary> /// Initializes this code generator /// </summary> /// <param name="unit">The unit to generate code for</param> /// <param name="binResource">Path to the automaton's binary resource</param> public ParserNetCodeGenerator(Unit unit, string binResource) { this.nmespace = Helper.GetNamespaceForCS(unit.Namespace == null ? unit.Grammar.Name : unit.Namespace); this.modifier = unit.Modifier; this.name = unit.Name; this.binResource = binResource; this.grammar = unit.Grammar; if (unit.Method == ParsingMethod.RNGLR1 || unit.Method == ParsingMethod.RNGLALR1) { this.parserType = "RNGLRParser"; this.automatonType = "RNGLRAutomaton"; } else { this.parserType = "LRkParser"; this.automatonType = "LRkAutomaton"; } terminals = unit.Expected; variables = new List <Variable>(unit.Grammar.Variables); virtuals = new List <Virtual>(unit.Grammar.Virtuals); actions = new List <Action>(unit.Grammar.Actions); variables.Sort(new Grammars.Symbol.IdComparer <Variable>()); virtuals.Sort(new Grammars.Symbol.IdComparer <Virtual>()); actions.Sort(new Grammars.Symbol.IdComparer <Action>()); }
/// <summary> /// Initializes this AST /// </summary> /// <param name="tokens">The table of tokens</param> /// <param name="variables">The table of variables</param> /// <param name="virtuals">The table of virtuals</param> public AST(TokenRepository tokens, ROList <Symbol> variables, ROList <Symbol> virtuals) { tableTokens = tokens; tableVariables = variables; tableVirtuals = virtuals; nodes = new BigList <Node>(); root = -1; }
/// <summary> /// Initializes this code generator /// </summary> /// <param name="unit">The unit to generate code for</param> /// <param name="binResource">Path to the automaton's binary resource</param> public LexerRustCodeGenerator(Unit unit, string binResource) { this.name = unit.Name; this.binResource = binResource; this.terminals = unit.Expected; this.contexts = unit.Grammar.Contexts; this.separator = unit.Separator; this.isParserRNGLR = (unit.Method == ParsingMethod.RNGLR1 || unit.Method == ParsingMethod.RNGLALR1); }
/// <summary> /// Initializes a new instance of the Lexer class with the given input /// </summary> /// <param name="automaton">DFA automaton for this lexer</param> /// <param name="terminals">Terminals recognized by this lexer</param> /// <param name="separator">SID of the separator token</param> /// <param name="input">Input to this lexer</param> protected BaseLexer(Automaton automaton, Symbol[] terminals, int separator, TextReader input) { this.automaton = automaton; symTerminals = new ROList <Symbol>(new List <Symbol>(terminals)); separatorID = separator; text = new StreamingText(input); tokens = new TokenRepository(symTerminals, text); RecoveryDistance = DEFAULT_RECOVERY_MATCHING_DISTANCE; }
/// <summary> /// Initializes this code generator /// </summary> /// <param name="unit">The unit to generate code for</param> /// <param name="binResource">Path to the automaton's binary resource</param> public LexerJavaCodeGenerator(Unit unit, string binResource) { this.nmespace = Helper.GetNamespaceForJava(unit.Namespace == null ? unit.Grammar.Name : unit.Namespace); this.modifier = unit.Modifier; this.name = unit.Name; this.binResource = binResource; this.terminals = unit.Expected; this.contexts = unit.Grammar.Contexts; this.separator = unit.Separator; }
/// <summary> /// Initializes the builder with the given stack size /// </summary> /// <param name="tokens">The table of tokens</param> /// <param name="variables">The table of parser variables</param> /// <param name="virtuals">The table of parser virtuals</param> public LRkASTBuilder(TokenRepository tokens, ROList <Symbol> variables, ROList <Symbol> virtuals) { poolSingle = new Pool <SubTree>(new SubTreeFactory(1), 512); pool128 = new Pool <SubTree>(new SubTreeFactory(128), 128); pool1024 = new Pool <SubTree>(new SubTreeFactory(1024), 16); stack = new SubTree[LRkParser.INIT_STACK_SIZE]; stackNext = 0; handle = new int[INIT_HANDLE_SIZE]; result = new AST(tokens, variables, virtuals); }
/// <summary> /// Initializes this parser generator /// </summary> /// <param name="unit">The unit to generate a parser for</param> public ParserLRkDataGenerator(Unit unit) { graph = unit.Graph; terminals = unit.Expected; variables = new List <Variable>(unit.Grammar.Variables); virtuals = new List <Virtual>(unit.Grammar.Virtuals); actions = new List <Action>(unit.Grammar.Actions); rules = new List <Rule>(unit.Grammar.Rules); variables.Sort(new Grammars.Symbol.IdComparer <Variable>()); virtuals.Sort(new Grammars.Symbol.IdComparer <Virtual>()); actions.Sort(new Grammars.Symbol.IdComparer <Action>()); }
/// <summary> /// Initializes this SPPF /// </summary> /// <param name="tokens">The token table</param> /// <param name="variables">The table of parser variables</param> /// <param name="virtuals">The table of parser virtuals</param> public SPPFBuilder(TokenRepository tokens, ROList <Symbol> variables, ROList <Symbol> virtuals) { poolHPs = new Pool <HistoryPart>(new HistoryPartFactory(), INIT_HISTORY_SIZE); history = new HistoryPart[INIT_HISTORY_SIZE]; nextHP = 0; sppf = new SPPF(); cacheChildren = new SPPFNodeRef[INIT_HANDLE_SIZE]; handleIndices = new int[INIT_HANDLE_SIZE]; handleActions = new TreeAction[INIT_HANDLE_SIZE]; stack = new int[INIT_HANDLE_SIZE]; result = new AST(tokens, variables, virtuals); }
/// <summary> /// Initializes a new instance of the LRkParser class with the given lexer /// </summary> /// <param name="variables">The parser's variables</param> /// <param name="virtuals">The parser's virtuals</param> /// <param name="actions">The parser's actions</param> /// <param name="lexer">The input lexer</param> protected BaseLRParser(Symbol[] variables, Symbol[] virtuals, SemanticAction[] actions, Lexer.BaseLexer lexer) { ModeRecoverErrors = DEFAULT_MODE_RECOVER; ModeDebug = DEFAULT_MODE_DEBUG; symVariables = new ROList <Symbol>(new List <Symbol>(variables)); symVirtuals = new ROList <Symbol>(new List <Symbol>(virtuals)); symActions = new ROList <SemanticAction>(actions != null ? new List <SemanticAction>(actions) : new List <SemanticAction>()); ModeRecoverErrors = true; allErrors = new List <ParseError>(); this.lexer = lexer; this.lexer.OnError += OnLexicalError; }
/// <summary> /// Loads the terminals from the specified lexers /// </summary> /// <param name="lexer">The lexer to investigate</param> private void LoadTerminals(BaseLexer lexer) { terminals = new List <Terminal>(); terminals.Add(Epsilon.Instance); terminals.Add(Dollar.Instance); ROList <Hime.Redist.Symbol> spec = lexer.Terminals; for (int i = 2; i != spec.Count; i++) { Hime.Redist.Symbol symbol = spec[i]; terminals.Add(new Terminal(symbol.ID, symbol.Name, "", null, 0)); } }
/// <summary> /// Initializes this parser reflection /// </summary> /// <param name="parserType">The parser's type</param> public ParserReflection(System.Type parserType) { ConstructorInfo[] ctors = parserType.GetConstructors(); ConstructorInfo parserCtor = null; System.Type lexerType = null; ConstructorInfo lexerCtor = null; for (int i = 0; i != ctors.Length; i++) { ParameterInfo[] parameters = ctors[i].GetParameters(); if (parameters.Length == 1) { parserCtor = ctors[i]; lexerType = parameters[0].ParameterType; break; } } lexerCtor = lexerType.GetConstructor(new [] { typeof(string) }); object lexer = lexerCtor.Invoke(new object[] { "" }); object parser = parserCtor.Invoke(new [] { lexer }); terminals = (lexer as BaseLexer).Terminals; variables = (parser as BaseLRParser).SymbolVariables; virtuals = (parser as BaseLRParser).SymbolVirtuals; automaton = new Automata.LRAutomaton(); string[] resources = parserType.Assembly.GetManifestResourceNames(); Stream stream = null; foreach (string existing in resources) { if (existing.EndsWith(parserType.Name + ".bin")) { stream = lexerType.Assembly.GetManifestResourceStream(existing); break; } } BinaryReader reader = new BinaryReader(stream); if ((typeof(LRkParser).IsAssignableFrom(parserType))) { LoadLRk(reader); } else { LoadRNGLR(reader); } reader.Close(); }
/// <summary> /// Gets the expected terminals for the specified state /// </summary> /// <param name="state">The DFA state</param> /// <param name="terminals">The possible terminals</param> /// <returns>The expected terminals</returns> public LRExpected GetExpected(int state, ROList <Symbol> terminals) { LRExpected result = new LRExpected(); int offset = ncols * state; for (int i = 0; i != terminals.Count; i++) { LRAction action = table[offset]; if (action.Code == LRActionCode.Shift) { result.Shifts.Add(terminals[i]); } else if (action.Code == LRActionCode.Reduce) { result.Reductions.Add(terminals[i]); } offset++; } return(result); }
/// <summary> /// Gets the expected terminals for the specified state /// </summary> /// <param name="state">The DFA state</param> /// <param name="terminals">The possible terminals</param> /// <returns>The expected terminals</returns> public LRExpected GetExpected(int state, ROList <Symbol> terminals) { LRExpected result = new LRExpected(); for (int i = 0; i != terminals.Count; i++) { Cell cell = table[state * ncols + i]; for (int j = 0; j != cell.ActionsCount; j++) { LRAction action = actions[cell.ActionsIndex + j]; if (action.Code == LRActionCode.Shift) { result.AddUniqueShift(terminals[i]); } else if (action.Code == LRActionCode.Reduce) { result.AddUniqueReduction(terminals[i]); } } } return(result); }
/// <summary> /// Exports the given NFA to a DOT graph in the specified file /// </summary> /// <param name="nfa">The NFA to export</param> /// <param name="file">DOT file to export to</param> public static void ExportDOT(NFA nfa, string file) { DOTSerializer serializer = new DOTSerializer("DFA", file); for (int i = 0; i != nfa.States.Count; i++) { NFAState state = nfa.States[i]; if (state.IsFinal) { ROList <FinalItem> items = state.Items; StringBuilder builder = new StringBuilder(i.ToString()); builder.Append(" : "); for (int j = 0; i != items.Count; i++) { if (i != 0) { builder.Append(", "); } builder.Append(items[j].ToString()); } serializer.WriteNode("state" + i, builder.ToString(), DOTNodeShape.doubleoctagon); } else { serializer.WriteNode("state" + i, i.ToString()); } } for (int i = 0; i != nfa.States.Count; i++) { NFAState state = nfa.States[i]; foreach (NFATransition transition in state.Transitions) { int to = nfa.States.IndexOf(transition.Next); serializer.WriteEdge("state" + i, "state" + to, transition.Span.ToString()); } } serializer.Close(); }
/// <summary> /// Initializes this error /// </summary> /// <param name="token">The unexpected token</param> /// <param name="expected">The expected terminals</param> public UnexpectedTokenError(Token token, ROList <Symbol> expected) : base(token.Position) { unexpected = token; this.expected = expected; }
/// <summary> /// Initializes this generator /// </summary> /// <param name="dfa">The dfa to serialize</param> /// <param name="expected">The terminals produced by the DFA</param> public LexerDataGenerator(Automata.DFA dfa, ROList <Grammars.Terminal> expected) { this.dfa = dfa; terminals = expected; }
/// <summary> /// Initializes this result as a success with the given AST /// </summary> /// <param name="errors">The list of errors</param> /// <param name="text">The parsed text</param> /// <param name="ast">The produced AST</param> internal ParseResult(ROList <ParseError> errors, Text text, AST ast) { this.errors = errors; this.text = text; this.ast = ast; }
/// <summary> /// Initializes this text /// </summary> /// <param name="terminals">The terminal symbols</param> /// <param name="text">The base text</param> public TokenRepository(ROList <Symbol> terminals, Text text) { this.terminals = terminals; this.text = text; this.cells = new BigList <Cell>(); }