internal void GenerateBlocks(AbstractLexer lexer)
 {
     parser.VisitToken = VisitingToken;
     AddBlocks(parser.Parse(lexer));
     parser.VisitToken = null;
 }
        /// <summary>
        /// Parses the specified lexer's tokens.
        /// </summary>
        /// <param name="lexer">The lexer.</param>
        /// <returns></returns>
        /// <exception cref="MonkeyspeakException">
        /// </exception>
        /// <exception cref="Exception">String length limit exceeded.</exception>
        public override IEnumerable <Trigger> Parse(AbstractLexer lexer)
        {
            Trigger     currentTrigger = Trigger.Undefined, lastTrigger = Trigger.Undefined;
            Token       token = Token.None, prevToken = default(Token), nextToken = default(Token);
            IExpression expr = null;

            foreach (var t in lexer.Read())
            {
                token = t;
                var tokenType = token.Type;

                if (!Expressions.Instance.ContainsKey(tokenType))
                {
                    continue;
                }

                if (token == default(Token))
                {
                    continue;
                }
                if (VisitToken != null)
                {
                    token = VisitToken(ref token);
                }

                var sourcePos = token.Position;

                string value = token.GetValue(lexer);

                //Logger.Debug<Parser>(token);
                switch (tokenType)
                {
                case TokenType.TRIGGER:
                    if (currentTrigger != Trigger.Undefined)
                    {
                        if (expr != null)
                        {
                            expr.Apply(currentTrigger);
                        }
                        yield return(currentTrigger);

                        lastTrigger    = currentTrigger;
                        currentTrigger = Trigger.Undefined;
                    }
                    expr           = Expressions.Create(tokenType, sourcePos, value);
                    lastTrigger    = currentTrigger;
                    currentTrigger = expr.GetValue <Trigger>();
                    break;

                case TokenType.VARIABLE:
                case TokenType.TABLE:
                    expr = Expressions.Create(tokenType, sourcePos, value);
                    break;

                case TokenType.STRING_LITERAL:
                    if (value.Length > Engine.Options.StringLengthLimit)
                    {
                        throw new MonkeyspeakException("String length limit exceeded.");
                    }
                    expr = Expressions.Create(tokenType, sourcePos, value);
                    break;

                case TokenType.NUMBER:
                    double val = double.Parse(value, System.Globalization.NumberStyles.AllowDecimalPoint
                                              | System.Globalization.NumberStyles.AllowLeadingSign
                                              | System.Globalization.NumberStyles.AllowExponent);
                    expr = Expressions.Create(tokenType, sourcePos, val);
                    break;

                case TokenType.COMMENT:
                    // we don't care about comments
                    break;

                case TokenType.PREPROCESSOR:
                    break;

                case TokenType.END_OF_FILE:
                    if (currentTrigger != Trigger.Undefined)
                    {
                        expr.Apply(currentTrigger);
                        yield return(currentTrigger);

                        lastTrigger    = currentTrigger;
                        currentTrigger = Trigger.Undefined;
                    }
                    break;

                default: break;
                }
                if (expr != null)
                {
                    if (currentTrigger != Trigger.Undefined)
                    {
                        expr.Apply(currentTrigger);
                    }
                    expr = null;
                }
            }
            if (currentTrigger != Trigger.Undefined)
            {
                yield return(currentTrigger);
            }
        }