Exemple #1
0
        public static SyntaxValue ReadValue(PositionedTextReader r, Optional <Dictionary <Object, TextRange> > TextRanges)
        {
            int State         = 0;
            var StartPosition = r.CurrentPosition;
            var States        = new Stack <int>();
            var Rules         = new Stack <SyntaxRule>();
            var CurrentRule   = Optional <SyntaxRule> .Empty;

            void Push()
            {
                States.Push(State);
                Rules.Push(CurrentRule.Value);
            }

            void Proceed()
            {
                CurrentRule = Optional <SyntaxRule> .Empty;
            }

            Exception MakeIllegalSyntaxRule()
            {
                var FilePath = r.FilePath;
                var Message  = CurrentRule.OnSome ? "IllegalSyntaxRule '" + CurrentRule.Value._Tag.ToString() + "'" : !r.EndOfText ? "InvalidChar '" + r.Peek() + "'" : "InvalidEndOfText";

                if (CurrentRule.OnSome && TextRanges.OnSome && TextRanges.Value.ContainsKey(CurrentRule.Value))
                {
                    var Range = TextRanges.Value[CurrentRule.Value];
                    if (FilePath.OnSome)
                    {
                        return(new InvalidOperationException(FilePath.Value + Range.ToString() + ": " + Message));
                    }
                    else
                    {
                        return(new InvalidOperationException(Range.ToString() + ": " + Message));
                    }
                }
                else if (FilePath.OnSome)
                {
                    return(new InvalidOperationException(FilePath.Value + r.CurrentPosition.ToString() + ": " + Message));
                }
                else
                {
                    return(new InvalidOperationException(r.CurrentPosition.ToString() + ": " + Message));
                }
            }

            T MarkRange <T>(T Rule, Object StartToken, Object EndToken)
            {
                if (TextRanges.OnSome)
                {
                    var d = TextRanges.Value;
                    if (d.ContainsKey(StartToken) && d.ContainsKey(EndToken))
                    {
                        var Range = new TextRange(d[StartToken].Start, d[EndToken].End);
                        d.Add(Rule, Range);
                    }
                }
                return(Rule);
            }

            void Reduce1(Func <SyntaxRule, SyntaxRule> Translator)
            {
                var Rule1 = Rules.Pop();

                CurrentRule = Translator(Rule1);
                State       = States.Pop();
            }

            void Reduce2(Func <SyntaxRule, SyntaxRule, SyntaxRule> Translator)
            {
                var Rule2 = Rules.Pop();
                var Rule1 = Rules.Pop();

                CurrentRule = Translator(Rule1, Rule2);
                States.Pop();
                State = States.Pop();
            }

            void Reduce3(Func <SyntaxRule, SyntaxRule, SyntaxRule, SyntaxRule> Translator)
            {
                var Rule3 = Rules.Pop();
                var Rule2 = Rules.Pop();
                var Rule1 = Rules.Pop();

                CurrentRule = Translator(Rule1, Rule2, Rule3);
                States.Pop();
                States.Pop();
                State = States.Pop();
            }

            void Reduce5(Func <SyntaxRule, SyntaxRule, SyntaxRule, SyntaxRule, SyntaxRule, SyntaxRule> Translator)
            {
                var Rule5 = Rules.Pop();
                var Rule4 = Rules.Pop();
                var Rule3 = Rules.Pop();
                var Rule2 = Rules.Pop();
                var Rule1 = Rules.Pop();

                CurrentRule = Translator(Rule1, Rule2, Rule3, Rule4, Rule5);
                States.Pop();
                States.Pop();
                States.Pop();
                States.Pop();
                State = States.Pop();
            }

            while (true)
            {
                while (CurrentRule.OnNone && !r.EndOfText)
                {
                    CurrentRule = TokenParser.ReadToken(r, TextRanges);
                    if (CurrentRule.OnSome && CurrentRule.Value.OnWhitespace)
                    {
                        CurrentRule = Optional <SyntaxRule> .Empty;
                    }
                }
                if (CurrentRule.OnNone)
                {
                    throw MakeIllegalSyntaxRule();
                }
                var c = CurrentRule.Value;
                if (State == 0)
                {
                    if (c.OnLeftBrace)
                    {
                        Push();
                        Proceed();
                        State = 1;
                    }
                    else if (c.OnLeftBracket)
                    {
                        Push();
                        Proceed();
                        State = 2;
                    }
                    else if (c.OnValue)
                    {
                        var Value = c.Value;
                        while (!r.EndOfText)
                        {
                            CurrentRule = TokenParser.ReadToken(r, TextRanges);
                            if (CurrentRule.OnSome && !CurrentRule.Value.OnWhitespace)
                            {
                                throw MakeIllegalSyntaxRule();
                            }
                        }
                        return(Value);
                    }
                    else if (c.OnObject)
                    {
                        Push();
                        Proceed();
                        Reduce1(o => MarkRange(SyntaxRule.CreateValue(MarkRange(SyntaxValue.CreateObject(o.Object), o, o)), o, o));
                    }
                    else if (c.OnArray)
                    {
                        Push();
                        Proceed();
                        Reduce1(a => MarkRange(SyntaxRule.CreateValue(MarkRange(SyntaxValue.CreateArray(a.Array), a, a)), a, a));
                    }
                    else if (c.OnLiteral)
                    {
                        Push();
                        Proceed();
                        Reduce1(l => MarkRange(SyntaxRule.CreateValue(MarkRange(SyntaxValue.CreateLiteral(l.Literal), l, l)), l, l));
                    }
                    else
                    {
                        throw MakeIllegalSyntaxRule();
                    }
                }
                else if (State == 1)
                {
                    if (c.OnRightBrace)
                    {
                        Push();
                        Proceed();
                        Reduce2((LeftBrace, RightBrace) => MarkRange(SyntaxRule.CreateObject(MarkRange(new SyntaxObject {
                            Members = Optional <SyntaxMembers> .Empty
                        }, LeftBrace, RightBrace)), LeftBrace, RightBrace));
                    }
                    else if (c.OnLiteral && c.Literal.OnStringValue)
                    {
                        Push();
                        Proceed();
                        State = 4;
                    }
                    else if (c.OnMembers)
                    {
                        Push();
                        Proceed();
                        State = 3;
                    }
                    else
                    {
                        throw MakeIllegalSyntaxRule();
                    }
                }
                else if (State == 2)
                {
                    if (c.OnLeftBrace)
                    {
                        Push();
                        Proceed();
                        State = 1;
                    }
                    else if (c.OnLeftBracket)
                    {
                        Push();
                        Proceed();
                        State = 2;
                    }
                    else if (c.OnRightBracket)
                    {
                        Push();
                        Proceed();
                        Reduce2((LeftBracket, RightBracket) => MarkRange(SyntaxRule.CreateArray(MarkRange(new SyntaxArray {
                            Elements = Optional <SyntaxElements> .Empty
                        }, LeftBracket, RightBracket)), LeftBracket, RightBracket));
                    }
                    else if (c.OnValue)
                    {
                        Push();
                        Proceed();
                        Reduce1(v => MarkRange(SyntaxRule.CreateElements(MarkRange(SyntaxElements.CreateSingle(v.Value), v, v)), v, v));
                    }
                    else if (c.OnObject)
                    {
                        Push();
                        Proceed();
                        Reduce1(o => MarkRange(SyntaxRule.CreateValue(MarkRange(SyntaxValue.CreateObject(o.Object), o, o)), o, o));
                    }
                    else if (c.OnArray)
                    {
                        Push();
                        Proceed();
                        Reduce1(a => MarkRange(SyntaxRule.CreateValue(MarkRange(SyntaxValue.CreateArray(a.Array), a, a)), a, a));
                    }
                    else if (c.OnLiteral)
                    {
                        Push();
                        Proceed();
                        Reduce1(l => MarkRange(SyntaxRule.CreateValue(MarkRange(SyntaxValue.CreateLiteral(l.Literal), l, l)), l, l));
                    }
                    else if (c.OnElements)
                    {
                        Push();
                        Proceed();
                        State = 5;
                    }
                    else
                    {
                        throw MakeIllegalSyntaxRule();
                    }
                }
                else if (State == 3)
                {
                    if (c.OnRightBrace)
                    {
                        Push();
                        Proceed();
                        Reduce3((LeftBrace, m, RightBrace) => MarkRange(SyntaxRule.CreateObject(MarkRange(new SyntaxObject {
                            Members = m.Members
                        }, LeftBrace, RightBrace)), LeftBrace, RightBrace));
                    }
                    else if (c.OnComma)
                    {
                        Push();
                        Proceed();
                        State = 6;
                    }
                    else if (c.OnMembers)
                    {
                        Push();
                        Proceed();
                        State = 3;
                    }
                    else
                    {
                        throw MakeIllegalSyntaxRule();
                    }
                }
                else if (State == 4)
                {
                    if (c.OnColon)
                    {
                        Push();
                        Proceed();
                        State = 7;
                    }
                    else
                    {
                        throw MakeIllegalSyntaxRule();
                    }
                }
                else if (State == 5)
                {
                    if (c.OnRightBracket)
                    {
                        Push();
                        Proceed();
                        Reduce3((LeftBracket, e, RightBracket) => MarkRange(SyntaxRule.CreateArray(MarkRange(new SyntaxArray {
                            Elements = e.Elements
                        }, LeftBracket, RightBracket)), LeftBracket, RightBracket));
                    }
                    else if (c.OnComma)
                    {
                        Push();
                        Proceed();
                        State = 8;
                    }
                    else
                    {
                        throw MakeIllegalSyntaxRule();
                    }
                }
                else if (State == 6)
                {
                    if (c.OnLiteral && c.Literal.OnStringValue)
                    {
                        Push();
                        Proceed();
                        State = 9;
                    }
                    else
                    {
                        throw MakeIllegalSyntaxRule();
                    }
                }
                else if (State == 7)
                {
                    if (c.OnLeftBrace)
                    {
                        Push();
                        Proceed();
                        State = 1;
                    }
                    else if (c.OnLeftBracket)
                    {
                        Push();
                        Proceed();
                        State = 2;
                    }
                    else if (c.OnRightBracket)
                    {
                        Push();
                        Proceed();
                        Reduce2((LeftBracket, RightBracket) => MarkRange(SyntaxRule.CreateArray(MarkRange(new SyntaxArray {
                            Elements = Optional <SyntaxElements> .Empty
                        }, LeftBracket, RightBracket)), LeftBracket, RightBracket));
                    }
                    else if (c.OnValue)
                    {
                        Push();
                        Proceed();
                        Reduce3((s, Colon, v) => MarkRange(SyntaxRule.CreateMembers(MarkRange(SyntaxMembers.CreateSingle(new Tuple <TokenLiteral, SyntaxValue>(s.Literal, v.Value)), s, v)), s, v));
                    }
                    else if (c.OnObject)
                    {
                        Push();
                        Proceed();
                        Reduce1(o => MarkRange(SyntaxRule.CreateValue(MarkRange(SyntaxValue.CreateObject(o.Object), o, o)), o, o));
                    }
                    else if (c.OnArray)
                    {
                        Push();
                        Proceed();
                        Reduce1(a => MarkRange(SyntaxRule.CreateValue(MarkRange(SyntaxValue.CreateArray(a.Array), a, a)), a, a));
                    }
                    else if (c.OnLiteral)
                    {
                        Push();
                        Proceed();
                        Reduce1(l => MarkRange(SyntaxRule.CreateValue(MarkRange(SyntaxValue.CreateLiteral(l.Literal), l, l)), l, l));
                    }
                    else
                    {
                        throw MakeIllegalSyntaxRule();
                    }
                }
                else if (State == 8)
                {
                    if (c.OnLeftBrace)
                    {
                        Push();
                        Proceed();
                        State = 1;
                    }
                    else if (c.OnLeftBracket)
                    {
                        Push();
                        Proceed();
                        State = 2;
                    }
                    else if (c.OnRightBracket)
                    {
                        Push();
                        Proceed();
                        Reduce2((LeftBracket, RightBracket) => MarkRange(SyntaxRule.CreateArray(MarkRange(new SyntaxArray {
                            Elements = Optional <SyntaxElements> .Empty
                        }, LeftBracket, RightBracket)), LeftBracket, RightBracket));
                    }
                    else if (c.OnValue)
                    {
                        Push();
                        Proceed();
                        Reduce3((e, Comma, v) => MarkRange(SyntaxRule.CreateElements(MarkRange(SyntaxElements.CreateMultiple(new Tuple <SyntaxElements, SyntaxValue>(e.Elements, v.Value)), e, v)), e, v));
                    }
                    else if (c.OnObject)
                    {
                        Push();
                        Proceed();
                        Reduce1(o => MarkRange(SyntaxRule.CreateValue(MarkRange(SyntaxValue.CreateObject(o.Object), o, o)), o, o));
                    }
                    else if (c.OnArray)
                    {
                        Push();
                        Proceed();
                        Reduce1(a => MarkRange(SyntaxRule.CreateValue(MarkRange(SyntaxValue.CreateArray(a.Array), a, a)), a, a));
                    }
                    else if (c.OnLiteral)
                    {
                        Push();
                        Proceed();
                        Reduce1(l => MarkRange(SyntaxRule.CreateValue(MarkRange(SyntaxValue.CreateLiteral(l.Literal), l, l)), l, l));
                    }
                    else
                    {
                        throw MakeIllegalSyntaxRule();
                    }
                }
                else if (State == 9)
                {
                    if (c.OnColon)
                    {
                        Push();
                        Proceed();
                        State = 10;
                    }
                    else
                    {
                        throw MakeIllegalSyntaxRule();
                    }
                }
                else if (State == 10)
                {
                    if (c.OnLeftBrace)
                    {
                        Push();
                        Proceed();
                        State = 1;
                    }
                    else if (c.OnLeftBracket)
                    {
                        Push();
                        Proceed();
                        State = 2;
                    }
                    else if (c.OnRightBracket)
                    {
                        Push();
                        Proceed();
                        Reduce2((LeftBracket, RightBracket) => MarkRange(SyntaxRule.CreateArray(MarkRange(new SyntaxArray {
                            Elements = Optional <SyntaxElements> .Empty
                        }, LeftBracket, RightBracket)), LeftBracket, RightBracket));
                    }
                    else if (c.OnValue)
                    {
                        Push();
                        Proceed();
                        Reduce5((m, Comma, s, Colon, v) => MarkRange(SyntaxRule.CreateMembers(MarkRange(SyntaxMembers.CreateMultiple(new Tuple <SyntaxMembers, TokenLiteral, SyntaxValue>(m.Members, s.Literal, v.Value)), m, v)), m, v));
                    }
                    else if (c.OnObject)
                    {
                        Push();
                        Proceed();
                        Reduce1(o => MarkRange(SyntaxRule.CreateValue(MarkRange(SyntaxValue.CreateObject(o.Object), o, o)), o, o));
                    }
                    else if (c.OnArray)
                    {
                        Push();
                        Proceed();
                        Reduce1(a => MarkRange(SyntaxRule.CreateValue(MarkRange(SyntaxValue.CreateArray(a.Array), a, a)), a, a));
                    }
                    else if (c.OnLiteral)
                    {
                        Push();
                        Proceed();
                        Reduce1(l => MarkRange(SyntaxRule.CreateValue(MarkRange(SyntaxValue.CreateLiteral(l.Literal), l, l)), l, l));
                    }
                    else
                    {
                        throw MakeIllegalSyntaxRule();
                    }
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }
        }
Exemple #2
0
        public static SyntaxRule ReadNumberLiteral(PositionedTextReader r, Optional <Dictionary <Object, TextRange> > TextRanges)
        {
            int    State           = 0;
            var    StartPosition   = r.CurrentPosition;
            bool   NegativeSign    = false;
            double IntegerPart     = 0;
            double FractionalPart  = 0;
            double FractionalBase  = 1;
            bool   ExpNegativeSign = false;
            double ExpPart         = 0;

            void Proceed()
            {
                r.Read();
            }

            Exception MakeIllegalChar()
            {
                var FilePath = r.FilePath;
                var Message  = !r.EndOfText ? "IllegalChar '" + r.Peek() + "'" : "InvalidEndOfText";

                if (FilePath.OnSome)
                {
                    return(new InvalidOperationException(FilePath.Value + r.CurrentPosition.ToString() + ": " + Message));
                }
                else
                {
                    return(new InvalidOperationException(r.CurrentPosition.ToString() + ": " + Message));
                }
            }

            T MarkRange <T>(T Rule)
            {
                if (TextRanges.OnSome)
                {
                    var Range = new TextRange(StartPosition, r.CurrentPosition);
                    TextRanges.Value.Add(Rule, Range);
                }
                return(Rule);
            }

            Func <double> GetResult = () =>
            {
                var d = ((NegativeSign ? -1 : 1) * (IntegerPart + FractionalPart / FractionalBase)) * Math.Pow(10, (ExpNegativeSign ? -1 : 1) * ExpPart);
                return(d);
            };

            while (true)
            {
                var c = r.EndOfText ? default(Char) : r.Peek();
                if (State == 0)
                {
                    if (c == '-')
                    {
                        NegativeSign = true;
                        Proceed();
                        State = 1;
                    }
                    else if (c == '0')
                    {
                        IntegerPart = 0;
                        Proceed();
                        State = 2;
                    }
                    else if ((c >= '1') && (c <= '9'))
                    {
                        IntegerPart = IntegerPart * 10 + (c - '0');
                        Proceed();
                        State = 3;
                    }
                    else
                    {
                        throw MakeIllegalChar();
                    }
                }
                else if (State == 1)
                {
                    if (c == '0')
                    {
                        IntegerPart = 0;
                        Proceed();
                        State = 2;
                    }
                    else if ((c >= '1') && (c <= '9'))
                    {
                        IntegerPart = IntegerPart * 10 + (c - '0');
                        Proceed();
                        State = 3;
                    }
                    else
                    {
                        throw MakeIllegalChar();
                    }
                }
                else if (State == 2)
                {
                    if (c == '.')
                    {
                        Proceed();
                        State = 4;
                    }
                    else if ((c == 'e') || (c == 'E'))
                    {
                        Proceed();
                        State = 5;
                    }
                    else
                    {
                        return(MarkRange(SyntaxRule.CreateLiteral(MarkRange(TokenLiteral.CreateNumberValue(GetResult())))));
                    }
                }
                else if ((State == 3) || (State == 6))
                {
                    if (c == '.')
                    {
                        Proceed();
                        State = 4;
                    }
                    else if ((c == 'e') || (c == 'E'))
                    {
                        Proceed();
                        State = 5;
                    }
                    else if ((c >= '0') && (c <= '9'))
                    {
                        IntegerPart = IntegerPart * 10 + (c - '0');
                        Proceed();
                        State = 6;
                    }
                    else
                    {
                        return(MarkRange(SyntaxRule.CreateLiteral(MarkRange(TokenLiteral.CreateNumberValue(GetResult())))));
                    }
                }
                else if (State == 4)
                {
                    if ((c >= '0') && (c <= '9'))
                    {
                        FractionalPart  = FractionalPart * 10 + (c - '0');
                        FractionalBase *= 10;
                        Proceed();
                        State = 7;
                    }
                    else
                    {
                        throw MakeIllegalChar();
                    }
                }
                else if (State == 5)
                {
                    if (c == '+')
                    {
                        ExpNegativeSign = false;
                        Proceed();
                        State = 8;
                    }
                    else if (c == '-')
                    {
                        ExpNegativeSign = true;
                        Proceed();
                        State = 8;
                    }
                    else if ((c >= '0') && (c <= '9'))
                    {
                        ExpPart = ExpPart * 10 + (c - '0');
                        Proceed();
                        State = 9;
                    }
                    else
                    {
                        throw MakeIllegalChar();
                    }
                }
                else if (State == 7)
                {
                    if ((c == 'e') || (c == 'E'))
                    {
                        Proceed();
                        State = 5;
                    }
                    else if ((c >= '0') && (c <= '9'))
                    {
                        FractionalPart  = FractionalPart * 10 + (c - '0');
                        FractionalBase *= 10;
                        Proceed();
                        State = 7;
                    }
                    else
                    {
                        return(MarkRange(SyntaxRule.CreateLiteral(MarkRange(TokenLiteral.CreateNumberValue(GetResult())))));
                    }
                }
                else if (State == 8)
                {
                    if ((c >= '0') && (c <= '9'))
                    {
                        ExpPart = ExpPart * 10 + (c - '0');
                        Proceed();
                        State = 9;
                    }
                    else
                    {
                        throw MakeIllegalChar();
                    }
                }
                else if (State == 9)
                {
                    if ((c >= '0') && (c <= '9'))
                    {
                        ExpPart = ExpPart * 10 + (c - '0');
                        Proceed();
                        State = 9;
                    }
                    else
                    {
                        return(MarkRange(SyntaxRule.CreateLiteral(MarkRange(TokenLiteral.CreateNumberValue(GetResult())))));
                    }
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }
        }
Exemple #3
0
        public static SyntaxRule ReadStringLiteral(PositionedTextReader r, Optional <Dictionary <Object, TextRange> > TextRanges)
        {
            int State         = 0;
            var StartPosition = r.CurrentPosition;
            var Chars         = new StringBuilder();
            int Hex           = 0;

            void Proceed()
            {
                r.Read();
            }

            Exception MakeIllegalChar()
            {
                var FilePath = r.FilePath;
                var Message  = !r.EndOfText ? "IllegalChar '" + r.Peek() + "'" : "InvalidEndOfText";

                if (FilePath.OnSome)
                {
                    return(new InvalidOperationException(FilePath.Value + r.CurrentPosition.ToString() + ": " + Message));
                }
                else
                {
                    return(new InvalidOperationException(r.CurrentPosition.ToString() + ": " + Message));
                }
            }

            T MarkRange <T>(T Rule)
            {
                if (TextRanges.OnSome)
                {
                    var Range = new TextRange(StartPosition, r.CurrentPosition);
                    TextRanges.Value.Add(Rule, Range);
                }
                return(Rule);
            };
            int?TryParseHex(Char c)
            {
                if ((c >= '0') && (c <= '9'))
                {
                    return(c - '0');
                }
                else if ((c >= 'A') && (c <= 'F'))
                {
                    return(c - 'A' + 10);
                }
                else if ((c >= 'a') && (c <= 'f'))
                {
                    return(c - 'a' + 10);
                }
                else
                {
                    return(null);
                }
            };

            while (true)
            {
                if (r.EndOfText)
                {
                    throw MakeIllegalChar();
                }
                var c = r.Peek();
                if (State == 0)
                {
                    if (c == '"')
                    {
                        Proceed();
                        State = 1;
                    }
                    else
                    {
                        throw MakeIllegalChar();
                    }
                }
                else if ((State == 1) || (State == 2) || (State == 4) || (State == 9))
                {
                    if (c == '"')
                    {
                        Proceed();
                        return(MarkRange(SyntaxRule.CreateLiteral(MarkRange(TokenLiteral.CreateStringValue(Chars.ToString())))));
                    }
                    else if (c == '\\')
                    {
                        Proceed();
                        State = 3;
                    }
                    else if (c >= '\u0020')
                    {
                        Chars.Append(c);
                        Proceed();
                        State = 2;
                    }
                    else
                    {
                        throw MakeIllegalChar();
                    }
                }
                else if (State == 3)
                {
                    if (c == 'u')
                    {
                        Proceed();
                        State = 5;
                    }
                    else if (c == '"')
                    {
                        Chars.Append('"');
                        Proceed();
                        State = 4;
                    }
                    else if (c == '\\')
                    {
                        Chars.Append('\\');
                        Proceed();
                        State = 4;
                    }
                    else if (c == '/')
                    {
                        Chars.Append('/');
                        Proceed();
                        State = 4;
                    }
                    else if (c == 'b')
                    {
                        Chars.Append('\b');
                        Proceed();
                        State = 4;
                    }
                    else if (c == 'f')
                    {
                        Chars.Append('\f');
                        Proceed();
                        State = 4;
                    }
                    else if (c == 'n')
                    {
                        Chars.Append('\n');
                        Proceed();
                        State = 4;
                    }
                    else if (c == 'r')
                    {
                        Chars.Append('\r');
                        Proceed();
                        State = 4;
                    }
                    else if (c == 't')
                    {
                        Chars.Append('\t');
                        Proceed();
                        State = 4;
                    }
                    else
                    {
                        throw MakeIllegalChar();
                    }
                }
                else if (State == 5)
                {
                    if (TryParseHex(c) is int h)
                    {
                        Hex = h;
                        Proceed();
                        State = 6;
                    }
                    else
                    {
                        throw MakeIllegalChar();
                    }
                }
                else if (State == 6)
                {
                    if (TryParseHex(c) is int h)
                    {
                        Hex = Hex * 16 + h;
                        Proceed();
                        State = 7;
                    }
                    else
                    {
                        throw MakeIllegalChar();
                    }
                }
                else if (State == 7)
                {
                    if (TryParseHex(c) is int h)
                    {
                        Hex = Hex * 16 + h;
                        Proceed();
                        State = 8;
                    }
                    else
                    {
                        throw MakeIllegalChar();
                    }
                }
                else if (State == 8)
                {
                    if (TryParseHex(c) is int h)
                    {
                        Hex = Hex * 16 + h;
                        Chars.Append((Char)(Hex));
                        Proceed();
                        State = 9;
                    }
                    else
                    {
                        throw MakeIllegalChar();
                    }
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }
        }
Exemple #4
0
        public static SyntaxRule ReadToken(PositionedTextReader r, Optional <Dictionary <Object, TextRange> > TextRanges)
        {
            int State         = 0;
            var StartPosition = r.CurrentPosition;

            void Proceed()
            {
                r.Read();
            }

            Exception MakeIllegalChar()
            {
                var FilePath = r.FilePath;
                var Message  = !r.EndOfText ? "IllegalChar '" + r.Peek() + "'" : "InvalidEndOfText";

                if (FilePath.OnSome)
                {
                    return(new InvalidOperationException(FilePath.Value + r.CurrentPosition.ToString() + ": " + Message));
                }
                else
                {
                    return(new InvalidOperationException(r.CurrentPosition.ToString() + ": " + Message));
                }
            }

            T MarkRange <T>(T Rule)
            {
                if (TextRanges.OnSome)
                {
                    var Range = new TextRange(StartPosition, r.CurrentPosition);
                    TextRanges.Value.Add(Rule, Range);
                }
                return(Rule);
            }

            while (true)
            {
                var c = r.EndOfText ? default(Char) : r.Peek();
                if (State == 0)
                {
                    if (c == '"')
                    {
                        return(ReadStringLiteral(r, TextRanges));
                    }
                    else if ((c == '-') || ((c >= '0') && (c <= '9')))
                    {
                        return(ReadNumberLiteral(r, TextRanges));
                    }
                    else if (c == '{')
                    {
                        Proceed();
                        return(MarkRange(SyntaxRule.CreateLeftBrace()));
                    }
                    else if (c == '}')
                    {
                        Proceed();
                        return(MarkRange(SyntaxRule.CreateRightBrace()));
                    }
                    else if (c == '[')
                    {
                        Proceed();
                        return(MarkRange(SyntaxRule.CreateLeftBracket()));
                    }
                    else if (c == ']')
                    {
                        Proceed();
                        return(MarkRange(SyntaxRule.CreateRightBracket()));
                    }
                    else if (c == ':')
                    {
                        Proceed();
                        return(MarkRange(SyntaxRule.CreateColon()));
                    }
                    else if (c == ',')
                    {
                        Proceed();
                        return(MarkRange(SyntaxRule.CreateComma()));
                    }
                    else if (c == 't')
                    {
                        Proceed();
                        if (r.EndOfText)
                        {
                            throw MakeIllegalChar();
                        }
                        c = r.Read();
                        if (c != 'r')
                        {
                            throw MakeIllegalChar();
                        }
                        if (r.EndOfText)
                        {
                            throw MakeIllegalChar();
                        }
                        c = r.Read();
                        if (c != 'u')
                        {
                            throw MakeIllegalChar();
                        }
                        if (r.EndOfText)
                        {
                            throw MakeIllegalChar();
                        }
                        c = r.Read();
                        if (c != 'e')
                        {
                            throw MakeIllegalChar();
                        }
                        return(MarkRange(SyntaxRule.CreateLiteral(MarkRange(TokenLiteral.CreateBooleanValue(true)))));
                    }
                    else if (c == 'f')
                    {
                        Proceed();
                        if (r.EndOfText)
                        {
                            throw MakeIllegalChar();
                        }
                        c = r.Read();
                        if (c != 'a')
                        {
                            throw MakeIllegalChar();
                        }
                        if (r.EndOfText)
                        {
                            throw MakeIllegalChar();
                        }
                        c = r.Read();
                        if (c != 'l')
                        {
                            throw MakeIllegalChar();
                        }
                        if (r.EndOfText)
                        {
                            throw MakeIllegalChar();
                        }
                        c = r.Read();
                        if (c != 's')
                        {
                            throw MakeIllegalChar();
                        }
                        if (r.EndOfText)
                        {
                            throw MakeIllegalChar();
                        }
                        c = r.Read();
                        if (c != 'e')
                        {
                            throw MakeIllegalChar();
                        }
                        return(MarkRange(SyntaxRule.CreateLiteral(MarkRange(TokenLiteral.CreateBooleanValue(false)))));
                    }
                    else if (c == 'n')
                    {
                        Proceed();
                        if (r.EndOfText)
                        {
                            throw MakeIllegalChar();
                        }
                        c = r.Read();
                        if (c != 'u')
                        {
                            throw MakeIllegalChar();
                        }
                        if (r.EndOfText)
                        {
                            throw MakeIllegalChar();
                        }
                        c = r.Read();
                        if (c != 'l')
                        {
                            throw MakeIllegalChar();
                        }
                        if (r.EndOfText)
                        {
                            throw MakeIllegalChar();
                        }
                        c = r.Read();
                        if (c != 'l')
                        {
                            throw MakeIllegalChar();
                        }
                        return(MarkRange(SyntaxRule.CreateLiteral(MarkRange(TokenLiteral.CreateNullValue()))));
                    }
                    else if ((c == '\t') || (c == '\n') || (c == '\r') || (c == ' '))
                    {
                        Proceed();
                        State = 1;
                    }
                    else
                    {
                        throw MakeIllegalChar();
                    }
                }
                else if (State == 1)
                {
                    if ((c == '\t') || (c == '\n') || (c == '\r') || (c == ' '))
                    {
                        Proceed();
                        State = 1;
                    }
                    else
                    {
                        return(MarkRange(SyntaxRule.CreateWhitespace()));
                    }
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }
        }