private ParserNode CreateNode(ParserContext context)
 {
     var node = new ParserNode(context, Reduction.Product);
     node.Children.AddRange(PopChildren(context).Reverse());
     node.EnsureResultComputed();
     return node;
 }
        public ParseResult Parse(Lexer lexer, ParserState initialState)
        {
            var context = new ParserContext(this, Automaton.Grammar, lexer);
            context.CurrentState = initialState;
            context.ParserStack.Push(new ParserNode(context, new GrammarDefinition("init"))
            {
                State = initialState
            });

            ReadNextToken(context);
            context.CurrentNode = new ParserNode(context, Automaton.Grammar.ToElement(lexer.Current.GetTokenCode()), lexer.Current);

            while (lexer.Current != null && context.Root == null && context.CurrentState != null)
            {
                // If no input and no default action (e.g. a grammar reduction),
                // that means we have to read the next token.
                if (context.CurrentNode == null && context.CurrentState.DefaultAction == null)
                    ReadNextToken(context);

                var action = GetNextAction(context);
                action.Execute(context);
            }

            lexer.SpecialBag.InsertNodesIntoAstNode(context.Root.Result);

            return ParseResult.FromContext(context);
        }
 public override void Execute(ParserContext context)
 {
     context.SendLogMessage(MessageSeverity.Message, ToString());
     CustomAction?.Invoke(context);
     context.ParserStack.Push(context.CurrentNode);
     context.CurrentState = context.CurrentNode.State = NextState;
     context.CurrentNode = null;
 }
        public override void Execute(ParserContext context)
        {
            context.SendLogMessage(MessageSeverity.Message, ToString());
            context.Root = context.ParserStack.Pop();
            context.CurrentNode = null;

            context.CurrentState = context.ParserStack.Peek().State;
        }
        public override void Execute(ParserContext context)
        {
            ReportSyntaxError(context);

            if (!TryRecover(context))
            {
                context.SendLogMessage(MessageSeverity.Error, "Failed to recover from syntax error.");
                context.CurrentState = null;
            }
        }
        private static void ReportSyntaxError(ParserContext context)
        {
            var expectedTokens = context.CurrentState.Actions.Keys.OfType<TokenGrammarElement>().ToArray();

            var node = context.CurrentNode;
            var message = string.Format("Unexpected {0} token. Expected {1}.",
                node.GrammarElement.Name,
                string.Join(" or ", expectedTokens.Select(x => x.Name)));

            context.SyntaxErrors.Add(new SyntaxError(node.Result.Range.Start, message, MessageSeverity.Error));
            context.SendLogMessage(MessageSeverity.Error, message);
        }
        public override void Execute(ParserContext context)
        {
            context.SendLogMessage(MessageSeverity.Message, ToString());
            var temp = context.CurrentNode;

            var node = context.CurrentNode = CreateNode(context);
            context.CurrentState = context.ParserStack.Peek().State;

            var action = context.CurrentState.Actions[node.GrammarElement];
            action.Execute(context);

            context.CurrentNode = temp;
        }
        public ParserAction GetNextAction(ParserContext context)
        {
            if (context.CurrentState.DefaultAction != null)
                return context.CurrentState.DefaultAction;

            ParserAction parserAction;
            if (!context.CurrentState.Actions.TryGetValue(context.CurrentNode.GrammarElement, out parserAction))
            {
                // Unexpected token or grammar pattern. Try to recover.
                return ErrorParserAction.Instance;
            }
            return parserAction;
        }
        private static ShiftParserAction PopToErrorShifter(ParserContext context)
        {
            ParserAction action = null;
            while (context.ParserStack.Any())
            {
                var state = context.ParserStack.Peek().State;
                context.SendLogMessage(MessageSeverity.Message, "Going back to state " + state.Id + ".");
                state.Actions.TryGetValue(Grammar.Error, out action);

                if (action is ShiftParserAction)
                    break;
                context.ParserStack.Pop();
            }

            return action as ShiftParserAction;
        }
        private static bool TryRecover(ParserContext context)
        {
            // Find shifter for error token, or fail recovery.
            var errorShifter = PopToErrorShifter(context);
            if (errorShifter == null)
                return false;

            // Execute shift.
            var currentNode = context.CurrentNode;
            context.CurrentNode = new ParserNode(context, Grammar.Error);
            errorShifter.Execute(context);
            context.CurrentNode = currentNode;

            while (true)
            {
                if (context.CurrentNode == null && context.CurrentState.DefaultAction == null)
                    context.Parser.ReadNextToken(context);

                var action = context.Parser.GetNextAction(context);

                // Discard tokens until legal action can be made.
                if (action is ErrorParserAction)
                {
                    if (context.CurrentNode.GrammarElement == Grammar.Eof)
                        return false;
                    context.Parser.ReadNextToken(context);
                }
                else
                {
                    action.Execute(context);
                }

                // If we found a synchronize token (i.e. a reduction with an error token), we have recovered.
                if (action is ReduceParserAction)
                    return true;
            }
        }
Exemple #11
0
 private void WarningEmptyStatement(ParserContext context, TextLocation location)
 {
     context.SyntaxErrors.Add(new SyntaxError(location,
         "Possible mistaken empty statement.",
         MessageSeverity.Warning));
 }
Exemple #12
0
 public abstract void Execute(ParserContext context);
Exemple #13
0
 public static ParseResult FromContext(ParserContext context)
 {
     return new ParseResult(context.Root, context.SyntaxErrors);
 }
 private IEnumerable<ParserNode> PopChildren(ParserContext context)
 {
     var childCount = Reduction.Sequence.Count;
     for (int i = 0; i < childCount; i++)
         yield return context.ParserStack.Pop();
 }
Exemple #15
0
 internal void SendLogMessage(ParserContext parserContext, MessageSeverity severity, string message)
 {
     if (EnableLogging)
         LogMessageReceived?.Invoke(this, new SourceParserLogEventArgs(parserContext, severity, message));
 }
 public void ReadNextToken(ParserContext context)
 {
     context.SendLogMessage(MessageSeverity.Message, "Read next token.");
     var lexer = context.Lexer;
     lexer.Advance();
     context.CurrentNode = new ParserNode(context, Automaton.Grammar.ToElement(lexer.Current.GetTokenCode()), lexer.Current);
 }
Exemple #17
0
 public SourceParserLogEventArgs(ParserContext parserContext, MessageSeverity messageSeverity, string message)
 {
     ParserContext = parserContext;
     MessageSeverity = messageSeverity;
     Message = message;
 }