Esempio n. 1
0
        public TokenRange GetMatchingRangeIn(TokenRange range)
        {
            Func <Token, bool> pred;
            int dir;

            switch (Value)
            {
            case "(": pred = t => t.Value != ")" || t.ParenDepth != ParenDepth; dir = +1; break;

            case ")": pred = t => t.Value != "(" || t.ParenDepth != ParenDepth; dir = -1; break;

            case "{": pred = t => t.Value != "}" || t.BraceDepth != BraceDepth; dir = +1; break;

            case "}": pred = t => t.Value != "{" || t.BraceDepth != BraceDepth; dir = -1; break;

            case "<": return
                    (new TokenRange(range.GetAllTokens(),
                                    Position + 1,
                                    AngleBracketParser.NotInsideAngleBrackets(
                                        new TokenRange(range.GetAllTokens(), Position, range.End))
                                    .Skip(1) // skip the "<", which is considered "outside"
                                    .First() // get the ">", which is likewise "outside"
                                    .Position));

            case "[": return
                    (new TokenRange(range.GetAllTokens(),
                                    Position + 1,
                                    BracketParser.NotInsideBrackets(
                                        new TokenRange(range.GetAllTokens(), Position, range.End))
                                    .Skip(1) // skip the "[", which is considered "outside"
                                    .First() // get the "]", which is likewise "outside"
                                    .Position));

            default: throw new NotSupportedException("Can't match this token!");
            }
            TokenRange r;

            if (dir == -1)
            {
                r = new TokenRange(range.GetAllTokens(), range.Begin, Position)
                    .RevTakeWhile(pred);
                if (r.Begin == range.Begin)
                {
                    throw new Error(SourceLine, "Syntax error: Unmatched " + Value);
                }
            }
            else
            {
                r = new TokenRange(range.GetAllTokens(), Position + 1, range.End)
                    .TakeWhile(pred);
                if (r.End == range.End)
                {
                    throw new Error(SourceLine, "Syntax error: Unmatched " + Value);
                }
            }
            return(r);
        }
Esempio n. 2
0
        IEnumerable <TokenRange> SplitParameterList(TokenRange toks, string delimiter)
        {
            if (toks.Begin == toks.End)
            {
                yield break;
            }
            while (true)
            {
                Token comma = AngleBracketParser.NotInsideAngleBrackets(toks)
                              .FirstOrDefault(t => t.Value == delimiter && t.ParenDepth == toks.First().ParenDepth);
                if (comma == null)
                {
                    break;
                }
                yield return(range(toks.Begin, comma.Position));

                toks = range(comma.Position + 1, toks.End);
            }
            yield return(toks);
        }
Esempio n. 3
0
        IEnumerable <Token> NormalizeWhitespace(IEnumerable <Token> tokens)
        {
            bool inWhitespace = false;
            bool leading      = true;

            foreach (var tok in tokens)
            {
                if (!tok.IsWhitespace)
                {
                    if (inWhitespace && !leading)
                    {
                        yield return new Token {
                                   Value = " "
                        }
                    }
                    ;
                    inWhitespace = false;
                    yield return(tok);

                    leading = false;
                }
                else
                {
                    inWhitespace = true;
                }
            }
        }

        void ParseDeclaration(TokenRange tokens,
                              out Token name,
                              out TokenRange type,
                              out TokenRange initializer,
                              out bool constructorSyntax)
        {
            initializer = null;
            TokenRange beforeInitializer = tokens;

            constructorSyntax = false;

            Token equals = AngleBracketParser.NotInsideAngleBrackets(tokens)
                           .FirstOrDefault(t => t.Value == "=" && t.ParenDepth == tokens.First().ParenDepth);

            if (equals != null)
            {
                // type name = initializer;
                beforeInitializer = range(tokens.Begin, equals.Position);
                initializer       = range(equals.Position + 1, tokens.End);
            }
            else
            {
                Token paren = AngleBracketParser.NotInsideAngleBrackets(tokens)
                              .FirstOrDefault(t => t.Value == "(");
                if (paren != null)
                {
                    // type name(initializer);
                    constructorSyntax = true;
                    beforeInitializer = range(tokens.Begin, paren.Position);
                    initializer       =
                        range(paren.Position + 1, tokens.End)
                        .TakeWhile(t => t.ParenDepth > paren.ParenDepth);
                }
            }
            name = beforeInitializer.Last(NonWhitespace);
            if (beforeInitializer.Begin == name.Position)
            {
                throw new Error(beforeInitializer.First().SourceLine, "Declaration has no type.");
            }
            type = range(beforeInitializer.Begin, name.Position);
        }

        VarDeclaration ParseVarDeclaration(TokenRange tokens)
        {
            Token      name;
            TokenRange type, initializer;
            bool       constructorSyntax;

            ParseDeclaration(tokens, out name, out type, out initializer, out constructorSyntax);
            return(new VarDeclaration
            {
                name = name.Value,
                type = str(NormalizeWhitespace(type)),
                initializer = initializer == null ? "" : str(NormalizeWhitespace(initializer)),
                initializerConstructorSyntax = constructorSyntax
            });
        }