コード例 #1
0
                public static bool PeekAndParse(CharStream cs, out FTL.AST.Pattern pattern)
                {
                    // A quoted-pattern is the easiest to detect, so we'll try that first
                    if (cs.PeekNext() == '"')
                    {
                        pattern = ParseQuoted(cs);
                        return(true);
                    }

                    // it might still be an unquoted-pattern, but this is trickier to detect
                    // first let's try to detect a placeable and block-text
                    if (Placeable.Peek(cs) || AnyText.PeekBlockText(cs))
                    {
                        pattern = ParseUnquoted(cs);
                        return(true);
                    }

                    // if not any of the above, the only thing left is unquoted-text
                    int bufferPos = cs.Position;

                    WhiteSpace.Parse(cs);
                    char next = cs.PeekNext();

                    cs.Rewind(bufferPos);
                    if (!CharStream.IsEOF(next) && !CharStream.IsNL(next))
                    {
                        pattern = ParseUnquoted(cs);
                        return(true);
                    }

                    pattern = null;
                    return(false);
                }
コード例 #2
0
                public static FTL.AST.CallExpression Parse(CharStream cs, FTL.AST.StringPrimitive builtin)
                {
                    if (!Builtin.IsValid(builtin.Value))
                    {
                        throw cs.CreateException(
                                  string.Format("{0} is not a valid builtin, while one was expected", builtin.Value),
                                  null);
                    }

                    cs.SkipCharacter(PREFIX);
                    FTL.AST.ArgumentsList arguments = new FTL.AST.ArgumentsList();

                    while (cs.PeekNext() != POSTFIX)
                    {
                        WhiteSpace.Parse(cs);
                        arguments.AddArgument(Argument.Parse(cs));
                        WhiteSpace.Parse(cs);
                        if (cs.PeekNext() != ',')
                        {
                            break;                             // exit early, as no more arguments are expected
                        }
                        cs.SkipNext();                         // skip ','
                    }

                    // make sure last non-ws char is ')',
                    // otherwise something went wrong
                    cs.SkipCharacter(POSTFIX);

                    return(new FTL.AST.CallExpression(builtin, arguments));
                }
コード例 #3
0
                public static bool PeekAndParse(CharStream cs, out FTL.AST.MemberList memberList)
                {
                    // if next char is not a newline, we can just as well skip already
                    char next = cs.PeekNext();

                    if (CharStream.IsEOF(next) || !CharStream.IsNL(next))
                    {
                        memberList = null;
                        return(false);
                    }

                    // let's keep peeking further, requiring our buffer
                    int bufferPos = cs.Position;

                    NewLine.Parse(cs);
                    WhiteSpace.Parse(cs);
                    // we'll always want to rewind no matter what
                    bool isMemberList = Member.Peek(cs);

                    cs.Rewind(bufferPos);

                    if (isMemberList)
                    {
                        memberList = Parse(cs);
                        return(true);
                    }

                    memberList = null;
                    return(false);
                }
コード例 #4
0
                public static FTL.AST.Member Parse(CharStream cs)
                {
                    WhiteSpace.Parse(cs);

                    bool isDefault = false;

                    if (cs.PeekNext() == '*')
                    {
                        cs.SkipNext();
                        isDefault = true;
                    }

                    // Parse the MemberKey
                    cs.SkipCharacter('[');
                    FTL.AST.INode key = Memberkey.Parse(cs);
                    cs.SkipCharacter(']');

                    // skip optional space
                    WhiteSpace.Parse(cs);

                    // Parse the actual pattern
                    FTL.AST.Pattern pattern = Pattern.Parse(cs);

                    // and return it all
                    return(new FTL.AST.Member(key, pattern, isDefault));
                }
コード例 #5
0
                public static bool PeekBlockText(CharStream cs)
                {
                    char next = cs.PeekNext();

                    // if next char isn't a NewLine Character, we know for sure we
                    // are not dealing with a block-text
                    if (CharStream.IsEOF(next) || !CharStream.IsNL(next))
                    {
                        return(false);
                    }

                    // from here on out, we're still not sure if we're dealing with a block-text
                    // thus we start buffering so we can go back in time
                    // here we check if we have the following pattern: `NL __ '|'`
                    int bufferPos = cs.Position;

                    NewLine.Parse(cs);
                    WhiteSpace.Parse(cs);

                    // if the next unbuffered char is not '|' we're not dealing with a block-text
                    // and can return;
                    next = cs.PeekNext();
                    cs.Rewind(bufferPos);
                    return(next == '|');
                }
コード例 #6
0
                public static FTL.AST.INode Parse(CharStream cs)
                {
                    FTL.AST.INode expression = Expresson.Parse(cs);

                    int bufferPos = cs.Position;

                    WhiteSpace.Parse(cs);

                    if (cs.PeekNext() != SEPERATOR[0])
                    {
                        // it's not a select expression, so let's return early
                        cs.Rewind(bufferPos);
                        return(expression);
                    }

                    // it must be a select expression

                    cs.SkipString(SEPERATOR);

                    WhiteSpace.Parse(cs);

                    // we expect now a memberList (REQUIRED)
                    FTL.AST.MemberList memberList = MemberList.Parse(cs);

                    // skip extra new-line in case one is available
                    if (CharStream.IsNL(cs.PeekNext()))
                    {
                        NewLine.Parse(cs);
                    }

                    // return it all
                    return(new FTL.AST.SelectExpression(expression, memberList));
                }
コード例 #7
0
                // ([^{"] | '\{' | '\"')+
                public static FTL.AST.QuotedText ParseQuoted(CharStream cs)
                {
                    s_Buffer.Clear();
                    WhiteSpace.Parse(cs);

                    bool allowSC = false;
                    char next    = cs.PeekNext();

                    while (!CharStream.IsEOF(next) && !CharStream.IsNL(next) &&
                           (allowSC || (next != '{' && next != '"')))
                    {
                        s_Buffer.Add(next);
                        cs.SkipNext();
                        allowSC = !allowSC && next == '\\';
                        next    = cs.PeekNext();
                    }

                    if (s_Buffer.Count == 0)
                    {
                        throw cs.CreateException(
                                  "no quoted text could be parsed, while this was expected", null);
                    }

                    return(new FTL.AST.QuotedText(new string(s_Buffer.ToArray())));
                }
コード例 #8
0
                public static FTL.AST.INode Parse(CharStream cs)
                {
                    FTL.AST.INode result;

                    // if it's an identifier, it could be either simply be an identifier,
                    // or it could actually be a keyword-argument
                    if (Identifier.PeekAndParse(cs, out result))
                    {
                        int bufferPos = cs.Position;
                        // ignore any whitespace
                        WhiteSpace.Parse(cs);

                        // if we now encounter a `=` char, we'll assume it's a keyword-argument,
                        // and finish the parsing of that element,
                        // otherwise we'll assume it's simply an identifier and return early
                        if (cs.PeekNext() != '=')
                        {
                            cs.Rewind(bufferPos);
                            return(Expresson.ParseWithIdentifier(cs, result as FTL.AST.StringPrimitive));
                        }

                        cs.SkipNext();
                        WhiteSpace.Parse(cs);

                        FTL.AST.Pattern pattern = Pattern.ParseQuoted(cs);
                        return(new FTL.AST.KeywordArgument(
                                   result as L20n.FTL.AST.StringPrimitive,
                                   pattern));
                    }

                    // it's not an identifier, so is must be any non-identifier expression
                    return(Expresson.ParseNoneIdentifier(cs));
                }
コード例 #9
0
                private static FTL.AST.Section Parse(CharStream cs)
                {
                    cs.SkipString(PREFIX);
                    WhiteSpace.Parse(cs);
                    var keyword = Keyword.Parse(cs);

                    WhiteSpace.Parse(cs);
                    cs.SkipString(POSTFIX);

                    return(new FTL.AST.Section(keyword));
                }
コード例 #10
0
        protected override (bool isSuccess, Cursol cursol, T parsed) ParseCore(Cursol cursol)
        {
            var  current = cursol;
            bool isSuccess;

            do
            {
                (isSuccess, current, _) = WhiteSpace.Parse(current);
            } while (isSuccess);

            return(Parser.Parse(current));
        }
コード例 #11
0
                public static bool PeekAndParse(CharStream cs, out FTL.AST.INode result)
                {
                    if (!Peek(cs))
                    {
                        result = null;
                        return(false);
                    }

                    // skip prefix and optional space
                    cs.SkipCharacter(PREFIX);

                    FTL.AST.Placeable placeable = new FTL.AST.Placeable();
                    // parse all placeable-expressions
                    do
                    {
                        WhiteSpace.Parse(cs);
                        // optional newline
                        if (CharStream.IsNL(cs.PeekNext()))
                        {
                            NewLine.Parse(cs);
                            WhiteSpace.Parse(cs);
                        }
                        placeable.AddExpression(PlaceableExpression.Parse(cs));
                        WhiteSpace.Parse(cs);
                        if (cs.PeekNext() != ',')
                        {
                            break;
                        }

                        // keep going, until we have no more commas
                        cs.SkipNext();
                    } while(true);

                    // skip optional space
                    WhiteSpace.Parse(cs);
                    // optional newline
                    if (CharStream.IsNL(cs.PeekNext()))
                    {
                        NewLine.Parse(cs);
                        WhiteSpace.Parse(cs);
                    }

                    cs.SkipCharacter(POSTFIX);

                    result = placeable;
                    return(true);
                }
コード例 #12
0
        public void WhiteSpaceTests()
        {
            var stream = NCS("   \t\t  ");

            // This will read everything
            WhiteSpace.Parse(stream);
            // This will not read anything, but it's optional
            // so it will not give an exception
            WhiteSpace.Parse(stream);


            stream = NCS("   a <- foo");

            // This will read until 'a'
            WhiteSpace.Parse(stream);
            WhiteSpace.Parse(stream);
            Assert.AreEqual("a <- foo", stream.ReadUntilEnd());
        }
コード例 #13
0
                private static FTL.AST.Message Parse(CharStream cs, Context ctx, FTL.AST.StringPrimitive identifier)
                {
                    WhiteSpace.Parse(cs);
                    cs.SkipCharacter('=');
                    WhiteSpace.Parse(cs);

                    FTL.AST.Pattern pattern = null;
                    // check if we have a Pattern available
                    bool hasPattern = Pattern.PeekAndParse(cs, out pattern);

                    FTL.AST.MemberList memberList;
                    bool parsedMemberList = MemberList.PeekAndParse(cs, out memberList);

                    if (!parsedMemberList && !hasPattern)
                    {
                        throw cs.CreateException(
                                  "member-list was expected, as no pattern was found", null);
                    }

                    return(new FTL.AST.Message(identifier, pattern, memberList));
                }
コード例 #14
0
                public static FTL.AST.MemberList Parse(CharStream cs)
                {
                    // starts with a newline and optional newline
                    NewLine.Parse(cs);
                    WhiteSpace.Parse(cs);

                    FTL.AST.MemberList memberList = new FTL.AST.MemberList();
                    // parse first required member, as we always need at least 1
                    memberList.AddMember(Member.Parse(cs));

                    char next;
                    int  bufferPos;

                    do
                    {
                        next = cs.PeekNext();
                        if (CharStream.IsEOF(next) || !CharStream.IsNL(next))
                        {
                            break;
                        }

                        bufferPos = cs.Position;
                        NewLine.Parse(cs);
                        WhiteSpace.Parse(cs);

                        if (!Member.Peek(cs))
                        {
                            cs.Rewind(bufferPos);
                            break;
                        }

                        memberList.AddMember(Member.Parse(cs));
                    } while(true);

                    return(memberList);
                }
コード例 #15
0
                // NL __ '|' __ (unquoted-text | placeable)+
                public static bool PeekAndParseBlock(CharStream cs, out FTL.AST.INode result)
                {
                    char next = cs.PeekNext();

                    // if next char isn't a NewLine Character, we know for sure we
                    // are not dealing with a block-text
                    if (CharStream.IsEOF(next) || !CharStream.IsNL(next))
                    {
                        result = null;
                        return(false);
                    }

                    // from here on out, we're still not sure if we're dealing with a block-text
                    // thus we start buffering so we can go back in time
                    // here we check if we have the following pattern: `NL __ '|'`
                    int bufferPos = cs.Position;

                    NewLine.Parse(cs);
                    WhiteSpace.Parse(cs);

                    // if the next unbuffered char is not '|' we're not dealing with a block-text
                    // and can return;
                    if (cs.PeekNext() != '|')
                    {
                        cs.Rewind(bufferPos);
                        result = null;
                        return(false);
                    }

                    // we know for sure we're dealing with a block-text,
                    // buffer can be flushed and we can start checking for more lines as well;
                    FTL.AST.INode line;

                    FTL.AST.BlockText blockText = new FTL.AST.BlockText();
                    do
                    {
                        cs.SkipNext();                         // skip '|'

                        WhiteSpace.Parse(cs);

                        if (!Placeable.PeekAndParse(cs, out line))
                        {
                            // it's not a placeable, so it must be unquoted-text
                            line = ParseUnquoted(cs);
                        }

                        // add line
                        blockText.AddLine(line);

                        // peek if next char is a newline char
                        // otherwise we can stop early with trying
                        next = cs.PeekNext();
                        if (CharStream.IsEOF(next) || !CharStream.IsNL(next))
                        {
                            break;
                        }

                        // check if we have more lines
                        bufferPos = cs.Position;
                        NewLine.Parse(cs);
                        WhiteSpace.Parse(cs);


                        // as long as the next char is '|'
                        // we'll keep looping
                        if (cs.PeekNext() != '|')
                        {
                            cs.Rewind(bufferPos);
                            break;
                        }
                    } while(true);

                    result = blockText;
                    return(true);
                }