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(); } } }
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(); } } }
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(); } } }
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(); } } }