Пример #1
0
 /// <summary>Compares the elements of the token tree for equality.</summary>
 /// <remarks>Because <see cref="LNode"/>s are compared by value and not by
 /// reference, and LNodes can contain TokenTrees, TokenTrees should also be
 /// compared by value.</remarks>
 public bool Equals(TokenTree other)
 {
     if (other == null || Count != other.Count)
     {
         return(false);
     }
     return(this.SequenceEqual(other));
 }
Пример #2
0
 /// <summary>Compares the elements of the token tree for equality.</summary>
 /// <remarks>Because <see cref="LNode"/>s are compared by value and not by
 /// reference, and LNodes can contain TokenTrees, TokenTrees should also be
 /// compared by value.</remarks>
 public bool Equals(TokenTree other)
 {
     if (other == null)
     {
         return(false);
     }
     return(LinqToLists.SequenceEqual <Token>(this, other));
 }
Пример #3
0
        private void TestToLNode(Token t, ISourceFile file, string lesString)
        {
            LNode n = TokenTree.TokenToLNode(t, file);

            AreEqual(lesString, Les2LanguageService.Value.Print(n, null, ParsingMode.Expressions));
            AreEqual(file, n.Source);
            AreEqual(t.StartIndex, n.Range.StartIndex);
            AreEqual((t.Children != null && t.Children.Count > 0 ? t.Children.Last : t).EndIndex, n.Range.EndIndex);
        }
Пример #4
0
        public void ToBracketsLNodeTests()
        {
            var file  = EmptySourceFile.Unknown;
            var child = new TokenTree(file, new[] { new Token((int)TokenKind.Id, 6, 1, NodeStyle.Default, GSymbol.Get("x")) });

            TestToLNode(EmptySourceFile.Unknown, new List <Pair <Token, string> >()
            {
                P(new Token((int)TokenKind.LParen, 5, 1, 0, child), @"LParen(x)"),
                P(new Token((int)TokenKind.RParen, 7, 1, 0, null), @"RParen()"),
                P(new Token((int)TokenKind.LParen, 5, 1, 0, null), @"LParen()"),
                P(new Token((int)TokenKind.RParen, 7, 1, 0, null), @"RParen()"),
                P(new Token((int)TokenKind.LBrack, 5, 1, 0, child), @"LBrack(x)"),
                P(new Token((int)TokenKind.RBrack, 7, 1, 0, null), @"RBrack()"),
                P(new Token((int)TokenKind.LBrace, 5, 1, 0, child), @"LBrace(x)"),
                P(new Token((int)TokenKind.RBrace, 7, 1, 0, null), @"RBrace()"),
                P(new Token((int)TokenKind.Indent, 5, 1, 0, child), @"Indent(x)"),
                P(new Token((int)TokenKind.Dedent, 7, 1, 0, null), @"Dedent()"),
                P(new Token((int)TokenKind.LOther, 5, 1, 0, child), @"LOther(x)"),
                P(new Token((int)TokenKind.ROther, 7, 1, 0, null), @"ROther()"),
            });
        }
Пример #5
0
        void GatherChildren(ref Token openToken)
        {
            Debug.Assert(openToken.Value == null);
            if (openToken.Value != null && openToken.Children != null)
            {
                return;                 // wtf, it's already a tree
            }
            TK        ott            = openToken.Kind;
            int       oldIndentLevel = _source.IndentLevel;
            TokenTree children       = new TokenTree(_source.SourceFile);

            for (;;)
            {
                Token?t = LLNextToken();                  // handles LBrace, LParen, LBrack internally
                if (t == null)
                {
                    WriteError(openToken.StartIndex, "Reached end-of-file before '{0}' was closed", openToken);
                    break;
                }
                TK tt = t.Value.Kind;
                if (IsOpener(tt))
                {
                    var v = t.Value;
                    GatherChildren(ref v);
                    children.Add(v);
                    if (_closer != null && _closerMatched)
                    {
                        children.Add(_closer.Value);
                        _closer = null;
                    }
                }
                else if (IsCloser(tt))
                {
                    // indent must match dedent, '{' must match '}' (the parser
                    // can complain itself about "(]" and "[)" if it wants; we
                    // allow these to match because some languages might want it.)
                    bool dentMismatch = (ott == TK.Indent) != (tt == TK.Dedent);
                    if (dentMismatch || (ott == TK.LBrace) != (tt == TK.RBrace))
                    {
                        WriteError(openToken.StartIndex, "Opening '{0}' does not match closing '{1}' on line {2}",
                                   openToken.ToString(), t.Value.ToString(), SourceFile.IndexToLine(t.Value.StartIndex).Line);
                        // - If dentMismatch and ott == TK.Indent, do not close.
                        // - If dentMismatch and tt = TK.Dedent, close but do not match.
                        // - If the closer is more indented than the opener, do not close.
                        // - If the closer is less indented than the opener, close but do not match.
                        // - If the closer is the same indentation as the opener, close and match.
                        if (dentMismatch ? tt == TK.Dedent : IndentLevel <= oldIndentLevel)
                        {
                            // close
                            _closer        = t.Value;
                            _closerMatched = !dentMismatch && (IndentLevel == oldIndentLevel);
                            break;
                        }
                        else
                        {
                            children.Add(t.Value);                             // do not close
                        }
                    }
                    else
                    {
                        _closer        = t.Value;
                        _closerMatched = true;
                        break;
                    }
                }
                else
                {
                    children.Add(t.Value);
                }
            }
            openToken.Value = children;
        }
Пример #6
0
 public LNode ToLNode(ISourceFile file) => TokenTree.TokenToLNode(this, file);