Esempio n. 1
0
        /// <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);
            }
        });
Esempio n. 2
0
        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
        }