/// <summary> /// This is the method used by Piglets parserfactory to obtain preconfigured lexers. /// </summary> /// <param name="grammar">Grammar to generate lexers from</param> /// <param name="lexerSettings">Additional lexing settings</param> /// <returns>A lexer compatibe with the given grammars tokenizing rules</returns> internal static ILexer <T> ConfigureFromGrammar(IGrammar <T> grammar, ILexerSettings lexerSettings) => // This works because the grammar tokens will recieve the same token number // since they are assigned to this list in just the same way. AND BECAUSE the // end of input token is LAST. if this is changed it WILL break. // This might be considered dodgy later on, since it makes it kinda sorta hard to // use other lexers with Piglet. Let's see what happens, if anyone ever wants to write their // own lexer for Piglet. Configure(c => { c.Runtime = lexerSettings.Runtime; c.IgnoreCase = lexerSettings.IgnoreCase; List <ITerminal <T> > terminals = grammar.AllSymbols.OfType <ITerminal <T> >().ToList(); foreach (ITerminal <T> terminal in terminals) { if (terminal.RegExp != null) { c.Token(terminal.RegExp, terminal.OnParse); } } c.EndOfInputTokenNumber = terminals.FindIndex(f => f == grammar.EndOfInputTerminal); foreach (string ignored in lexerSettings.Ignore) { c.Ignore(ignored); } });
public ParserConfigurator() { nonTerminals = new List <NonTerminal <T> >(); terminals = new LinkedList <Terminal <T> >(); lexerSettings = new LexerSettingsImpl(); terminalPrecedences = new List <TerminalPrecedence>(); currentPrecedence = 0; // Create the Error token. This will create it as terminal 0, but in the end it will be the LAST terminal // second last is EndOfInput. This is sort of hackish and mainly due to the way the lexer is configured. ErrorToken = CreateTerminal(null, s => default(T)); ErrorToken.DebugName = "%ERROR%"; // Set some default settings LexerSettings.CreateLexer = true; LexerSettings.EscapeLiterals = true; LexerSettings.Ignore = new[] { "\\s+" }; // Ignore all whitespace by default }