/// <summary>
 /// Invoked when a block is entered to create a new statements context
 /// which will received all subsequent statements.
 /// </summary>
 public void EnterBlock(ParseTreeNode tag)
 {
     _blocks.Push(CurrentBlock);
     CurrentBlock = new BlockContext(tag);
 }
 /// <summary>
 /// Invoked when the end of a block has been reached.
 /// It resets the current statements context to the outer block.
 /// </summary>
 public void ExitBlock()
 {
     CurrentBlock = _blocks.Pop();
 }
示例#3
0
        protected bool _isRaw;     // true when the current block is raw

        public bool TryParse(StringSegment template, out IList <Statement> result, out IEnumerable <string> errors)
        {
            errors = Array.Empty <string>();

            Parser parser = null;

            _currentContext = new BlockContext(null);
            _contexts       = new Stack <BlockContext>();
            result          = _currentContext.Statements;

            try
            {
                int       previous = 0, index = 0;
                Statement s;

                while (true)
                {
                    previous = index;

                    if (!MatchTag(template, index, out var start, out var end))
                    {
                        index = template.Length;

                        if (index != previous)
                        {
                            // Consume last Text statement
                            ConsumeTextStatement(template, previous, index);
                        }

                        break;
                    }
                    else
                    {
                        if (parser == null)
                        {
                            parser = new Parser(_language);
                        }

                        if (start != previous)
                        {
                            // Consume current Text statement
                            ConsumeTextStatement(template, previous, start);
                        }

                        var tag  = template.Substring(start, end - start + 1);
                        var tree = parser.Parse(tag);

                        if (tree.HasErrors())
                        {
                            errors = tree
                                     .ParserMessages
                                     .Select(x => $"{x.Message} at line:{x.Location.Line}, col:{x.Location.Column}")
                                     .ToArray();

                            return(false);
                        }

                        switch (tree.Root.Term.Name)
                        {
                        case "output":
                            s = BuildOutputStatement(tree.Root);
                            break;

                        case "tag":
                            s = BuildTagStatement(tree.Root);
                            break;

                        default:
                            s = null;
                            break;
                        }

                        if (s != null)
                        {
                            _currentContext.Statements.Add(s);
                        }

                        index = end + 1;
                    }
                }