コード例 #1
0
ファイル: TokenParser.cs プロジェクト: blockspacer/niveum
        public TokenParserResult ReadToken(TextRange RangeInLine)
        {
            var s     = Text.GetTextInLine(RangeInLine);
            int Index = 0;

            Func <Boolean>     EndOfLine       = () => Index >= s.Length;
            Func <int, String> Peek            = n => s.Substring(Index, Math.Min(n, s.Length - Index));
            Action             Proceed         = () => Index += 1;
            Action <int>       ProceedMultiple = n => Index += n;

            Func <Optional <TextRange> > MakeRemainingChars = () => new TextRange {
                Start = Text.Calc(RangeInLine.Start, Index), End = RangeInLine.End
            };
            var NullRemainingChars = Optional <TextRange> .Empty;
            var NullToken          = Optional <SyntaxRule> .Empty;
            Func <int, int, TextRange> MakeTokenRange = (TokenStart, TokenEnd) => new TextRange {
                Start = Text.Calc(RangeInLine.Start, TokenStart), End = Text.Calc(RangeInLine.Start, TokenEnd)
            };
            Func <int, FileTextRange> MakeNextErrorTokenRange = n => new FileTextRange {
                Text = Text, Range = MakeTokenRange(Index, n)
            };

            var State = 0;

            var StartIndex = 0;
            Func <String, InvalidTokenException> MakeCurrentErrorTokenException = Message => new InvalidTokenException(Message, new FileTextRange {
                Text = Text, Range = MakeTokenRange(StartIndex, Index)
            }, Text.GetTextInLine(MakeTokenRange(StartIndex, Index)));
            Func <String, InvalidTokenException> MakeNextCharErrorTokenException = Message => new InvalidTokenException(Message, MakeNextErrorTokenRange(1), Peek(1));
            Action          MarkStart = () => StartIndex = Index;
            var             Output    = new List <Char>();
            Action <String> Write     = cs => Output.AddRange(cs);

            Func <Optional <SyntaxRule> > MakeSymbol = () =>
            {
                var Range  = MakeTokenRange(StartIndex, Index);
                var Symbol = new String(Output.ToArray());
                if (rBooleanLiteral.Match(Symbol).Success)
                {
                    var t  = TokenLiteral.CreateBooleanValue(!Symbol.Equals("false", StringComparison.Ordinal));
                    var st = SyntaxRule.CreateLiteral(t);
                    Positions.Add(t, Range);
                    Positions.Add(st, Range);
                    return(st);
                }
                else if (rIntLiteral.Match(Symbol).Success)
                {
                    var t  = TokenLiteral.CreateIntValue(NumericStrings.InvariantParseInt32(Symbol));
                    var st = SyntaxRule.CreateLiteral(t);
                    Positions.Add(t, Range);
                    Positions.Add(st, Range);
                    return(st);
                }
                else if (rRealLiteral.Match(Symbol).Success)
                {
                    var t  = TokenLiteral.CreateRealValue(NumericStrings.InvariantParseFloat64(Symbol));
                    var st = SyntaxRule.CreateLiteral(t);
                    Positions.Add(t, Range);
                    Positions.Add(st, Range);
                    return(st);
                }
                else if (rIdentifier.Match(Symbol).Success)
                {
                    var t = new TokenIdentifier {
                        Name = Symbol
                    };
                    var st = SyntaxRule.CreateIdentifier(t);
                    Positions.Add(t, Range);
                    Positions.Add(st, Range);
                    return(st);
                }
                else
                {
                    throw MakeCurrentErrorTokenException("InvalidToken");
                }
            };

            Func <Optional <SyntaxRule> > MakeBinaryOperator = () =>
            {
                var Range = MakeTokenRange(StartIndex, Index);
                var t     = new TokenBinaryOperator {
                    Name = new String(Output.ToArray())
                };
                var st = SyntaxRule.CreateBinaryOperator(t);
                Positions.Add(t, Range);
                Positions.Add(st, Range);
                return(st);
            };

            Func <Optional <SyntaxRule> > MakeUnaryOperator = () =>
            {
                var Range = MakeTokenRange(StartIndex, Index);
                var t     = new TokenUnaryOperator {
                    Name = new String(Output.ToArray())
                };
                var st = SyntaxRule.CreateUnaryOperator(t);
                Positions.Add(t, Range);
                Positions.Add(st, Range);
                return(st);
            };

            Func <Optional <SyntaxRule> > MakeLeftParen = () =>
            {
                var Range = MakeTokenRange(StartIndex, Index);
                var t     = new TokenLeftParen {
                };
                var st    = SyntaxRule.CreateLeftParen(t);
                Positions.Add(t, Range);
                Positions.Add(st, Range);
                return(st);
            };

            Func <Optional <SyntaxRule> > MakeRightParen = () =>
            {
                var Range = MakeTokenRange(StartIndex, Index);
                var t     = new TokenRightParen {
                };
                var st    = SyntaxRule.CreateRightParen(t);
                Positions.Add(t, Range);
                Positions.Add(st, Range);
                return(st);
            };

            Func <Optional <SyntaxRule> > MakeComma = () =>
            {
                var Range = MakeTokenRange(StartIndex, Index);
                var t     = new TokenComma {
                };
                var st    = SyntaxRule.CreateComma(t);
                Positions.Add(t, Range);
                Positions.Add(st, Range);
                return(st);
            };

            while (true)
            {
                if (State == 0)
                {
                    if (EndOfLine())
                    {
                        return(new TokenParserResult {
                            Token = NullToken, RemainingChars = NullRemainingChars
                        });
                    }
                    var c2 = Peek(2);
                    if (c2 == "&&" || c2 == "||" || c2 == "<=" || c2 == ">=" || c2 == "==" || c2 == "!=")
                    {
                        MarkStart();
                        Write(c2);
                        ProceedMultiple(2);
                        return(new TokenParserResult {
                            Token = MakeBinaryOperator(), RemainingChars = MakeRemainingChars()
                        });
                    }
                    var c = Peek(1);
                    if (c == " ")
                    {
                        Proceed();
                        continue;
                    }
                    if (c == "+" || c == "-" || c == "*" || c == "/" || c == "<" || c == ">")
                    {
                        MarkStart();
                        Write(c);
                        Proceed();
                        return(new TokenParserResult {
                            Token = MakeBinaryOperator(), RemainingChars = MakeRemainingChars()
                        });
                    }
                    if (c == "!")
                    {
                        MarkStart();
                        Write(c);
                        Proceed();
                        return(new TokenParserResult {
                            Token = MakeUnaryOperator(), RemainingChars = MakeRemainingChars()
                        });
                    }
                    if (c == "(")
                    {
                        MarkStart();
                        Proceed();
                        return(new TokenParserResult {
                            Token = MakeLeftParen(), RemainingChars = MakeRemainingChars()
                        });
                    }
                    if (c == ")")
                    {
                        MarkStart();
                        Proceed();
                        return(new TokenParserResult {
                            Token = MakeRightParen(), RemainingChars = MakeRemainingChars()
                        });
                    }
                    if (c == ",")
                    {
                        MarkStart();
                        Proceed();
                        return(new TokenParserResult {
                            Token = MakeComma(), RemainingChars = MakeRemainingChars()
                        });
                    }
                    if (rSymbol.Match(c).Success)
                    {
                        MarkStart();
                        Write(c);
                        Proceed();
                        State = 1;
                        continue;
                    }
                    throw MakeNextCharErrorTokenException("InvalidChar");
                }
                else if (State == 1)
                {
                    var c = Peek(1);
                    if (rSymbol.Match(c).Success)
                    {
                        Write(c);
                        Proceed();
                        continue;
                    }
                    return(new TokenParserResult {
                        Token = MakeSymbol(), RemainingChars = MakeRemainingChars()
                    });
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }
        }
コード例 #2
0
 /// <summary>标识符</summary>
 public static SyntaxRule CreateIdentifier(TokenIdentifier Value)
 {
     return(new SyntaxRule {
         _Tag = SyntaxRuleTag.Identifier, Identifier = Value
     });
 }