public SyntaxParserResult Parse(TextRange RangeInLine) { var TokenQueue = new LinkedList <SyntaxRule>(); var r = RangeInLine; while (true) { var t = tp.ReadToken(r); if (t.Token.OnSome) { TokenQueue.AddLast(t.Token.Some); } if (!t.RemainingChars.OnSome) { break; } r = t.RemainingChars.Some; } var StateStack = new Stack <int>(); var RuleStack = new Stack <SyntaxRule>(); var BinaryOperatorStack = new Stack <TokenBinaryOperator>(); var State = 0; //初始状态为0 StateStack.Push(State); Optional <SyntaxRule> Token = Optional <SyntaxRule> .Empty; Action <SyntaxRule, TextRange> Mark = (st, Range) => { if (st.OnExpr) { Positions.Add(st.Expr, Range); } else if (st.OnParameterList) { Positions.Add(st.ParameterList, Range); } else if (st.OnNonnullParameterList) { Positions.Add(st.NonnullParameterList, Range); } Positions.Add(st, Range); }; Func <Boolean> EndOfFile = () => TokenQueue.Count == 0; Action <int> Shift = NewState => { StateStack.Push(NewState); RuleStack.Push(TokenQueue.First.Value); TokenQueue.RemoveFirst(); }; Action <Func <SyntaxRule> > Reduce0 = f => { var st = f(); TextRange Range; if (EndOfFile()) { Range = new TextRange { Start = RangeInLine.End, End = RangeInLine.End }; } else { var NextTokenRange = Positions[Token.Some]; Range = new TextRange { Start = NextTokenRange.Start, End = NextTokenRange.Start }; } Mark(st, Range); TokenQueue.AddFirst(st); }; Action <Func <SyntaxRule, SyntaxRule> > Reduce1 = f => { var Rule0 = RuleStack.Pop(); StateStack.Pop(); var st = f(Rule0); var Rule0Range = Positions[Rule0]; var Range = Rule0Range; Mark(st, Range); TokenQueue.AddFirst(st); }; Action <Func <SyntaxRule, SyntaxRule, SyntaxRule> > Reduce2 = f => { var Rule1 = RuleStack.Pop(); var Rule0 = RuleStack.Pop(); StateStack.Pop(); StateStack.Pop(); var st = f(Rule0, Rule1); var Rule0Range = Positions[Rule0]; var Rule1Range = Positions[Rule1]; var Range = new TextRange { Start = Rule0Range.Start, End = Rule1Range.End }; Mark(st, Range); TokenQueue.AddFirst(st); }; Action <Func <SyntaxRule, SyntaxRule, SyntaxRule, SyntaxRule> > Reduce3 = f => { var Rule2 = RuleStack.Pop(); var Rule1 = RuleStack.Pop(); var Rule0 = RuleStack.Pop(); StateStack.Pop(); StateStack.Pop(); StateStack.Pop(); var st = f(Rule0, Rule1, Rule2); var Rule0Range = Positions[Rule0]; var Rule2Range = Positions[Rule2]; var Range = new TextRange { Start = Rule0Range.Start, End = Rule2Range.End }; Mark(st, Range); TokenQueue.AddFirst(st); }; Action <Func <SyntaxRule, SyntaxRule, SyntaxRule, SyntaxRule, SyntaxRule> > Reduce4 = f => { var Rule3 = RuleStack.Pop(); var Rule2 = RuleStack.Pop(); var Rule1 = RuleStack.Pop(); var Rule0 = RuleStack.Pop(); StateStack.Pop(); StateStack.Pop(); StateStack.Pop(); StateStack.Pop(); var st = f(Rule0, Rule1, Rule2, Rule3); var Rule0Range = Positions[Rule0]; var Rule3Range = Positions[Rule3]; var Range = new TextRange { Start = Rule0Range.Start, End = Rule3Range.End }; Mark(st, Range); TokenQueue.AddFirst(st); }; Action <SyntaxRule> Replace = f => { Mark(f, Positions[Token.Some]); Token = f; TokenQueue.First.Value = f; }; Func <InvalidSyntaxException> MakeInvalidEndOfFile = () => { var Range = new FileTextRange { Text = Text, Range = new TextRange { Start = RangeInLine.End, End = RangeInLine.End } }; return(new InvalidSyntaxException("InvalidEndOfFile", Range)); }; Func <InvalidSyntaxException> MakeInvalidSyntaxRule = () => { var tr = Positions[Token.Some]; var Range = new FileTextRange { Text = Text, Range = tr }; var t = Text.GetTextInLine(tr); return(new InvalidSyntaxException(String.Format("'{0}' : InvalidSyntaxRuleAtToken", t), Range)); }; while (true) { State = StateStack.Peek(); Token = EndOfFile() ? Optional <SyntaxRule> .Empty : TokenQueue.First.Value; if (State == 0) { if (!Token.OnSome) { throw MakeInvalidEndOfFile(); } var t = Token.Some; if (t.OnLiteral) { Shift(1); } else if (t.OnIdentifier) { Shift(2); } else if (t.OnBinaryOperator) { if (t.BinaryOperator.Name == "+" || t.BinaryOperator.Name == "-") { Replace(SyntaxRule.CreateUnaryOperator(new TokenUnaryOperator { Name = t.BinaryOperator.Name })); } else { throw MakeInvalidSyntaxRule(); } } else if (t.OnUnaryOperator) { Shift(3); } else if (t.OnLeftParen) { Shift(4); } else if (t.OnRightParen) { throw MakeInvalidSyntaxRule(); } else if (t.OnComma) { throw MakeInvalidSyntaxRule(); } else if (t.OnExpr) { Shift(5); } else if (t.OnParameterList) { throw MakeInvalidSyntaxRule(); } else if (t.OnNonnullParameterList) { throw MakeInvalidSyntaxRule(); } else { throw new InvalidOperationException(); } } else if (State == 1) { Reduce1(l => SyntaxRule.CreateExpr(SyntaxExpr.CreateLiteral(new ProductionLiteral { Literal = l.Literal }))); } else if (State == 2) { if (Token.OnSome && Token.Some.OnLeftParen) { Shift(6); } else { Reduce1(i => SyntaxRule.CreateExpr(SyntaxExpr.CreateVariable(new ProductionVariable { Identifier = i.Identifier }))); } } else if (State == 3) { if (!Token.OnSome) { throw MakeInvalidEndOfFile(); } var t = Token.Some; if (t.OnLiteral) { Shift(1); } else if (t.OnIdentifier) { Shift(2); } else if (t.OnBinaryOperator) { if (t.BinaryOperator.Name == "+" || t.BinaryOperator.Name == "-") { Replace(SyntaxRule.CreateUnaryOperator(new TokenUnaryOperator { Name = t.BinaryOperator.Name })); } else { throw MakeInvalidSyntaxRule(); } } else if (t.OnUnaryOperator) { Shift(3); } else if (t.OnLeftParen) { Shift(4); } else if (t.OnRightParen) { throw MakeInvalidSyntaxRule(); } else if (t.OnComma) { throw MakeInvalidSyntaxRule(); } else if (t.OnExpr) { Shift(7); } else if (t.OnParameterList) { throw MakeInvalidSyntaxRule(); } else if (t.OnNonnullParameterList) { throw MakeInvalidSyntaxRule(); } else { throw new InvalidOperationException(); } } else if (State == 4) { if (!Token.OnSome) { throw MakeInvalidEndOfFile(); } var t = Token.Some; if (t.OnLiteral) { Shift(1); } else if (t.OnIdentifier) { Shift(2); } else if (t.OnBinaryOperator) { if (t.BinaryOperator.Name == "+" || t.BinaryOperator.Name == "-") { Replace(SyntaxRule.CreateUnaryOperator(new TokenUnaryOperator { Name = t.BinaryOperator.Name })); } else { throw MakeInvalidSyntaxRule(); } } else if (t.OnUnaryOperator) { Shift(3); } else if (t.OnLeftParen) { Shift(4); } else if (t.OnRightParen) { throw MakeInvalidSyntaxRule(); } else if (t.OnComma) { throw MakeInvalidSyntaxRule(); } else if (t.OnExpr) { Shift(8); } else if (t.OnParameterList) { throw MakeInvalidSyntaxRule(); } else if (t.OnNonnullParameterList) { throw MakeInvalidSyntaxRule(); } else { throw new InvalidOperationException(); } } else if (State == 5) { if (!Token.OnSome) { return(new SyntaxParserResult { Syntax = RuleStack.Single().Expr }); } var t = Token.Some; if (t.OnBinaryOperator) { BinaryOperatorStack.Push(t.BinaryOperator); Shift(9); } else { throw MakeInvalidSyntaxRule(); } } else if (State == 6) { if (!Token.OnSome) { throw MakeInvalidEndOfFile(); } var t = Token.Some; if (t.OnLiteral) { Shift(1); } else if (t.OnIdentifier) { Shift(2); } else if (t.OnBinaryOperator) { if (t.BinaryOperator.Name == "+" || t.BinaryOperator.Name == "-") { Replace(SyntaxRule.CreateUnaryOperator(new TokenUnaryOperator { Name = t.BinaryOperator.Name })); } else { throw MakeInvalidSyntaxRule(); } } else if (t.OnUnaryOperator) { Shift(3); } else if (t.OnLeftParen) { Shift(4); } else if (t.OnRightParen) { Reduce0(() => SyntaxRule.CreateParameterList(SyntaxParameterList.CreateNull(new ProductionNullParameterList { }))); } else if (t.OnComma) { throw MakeInvalidSyntaxRule(); } else if (t.OnExpr) { Shift(10); } else if (t.OnParameterList) { Shift(11); } else if (t.OnNonnullParameterList) { Shift(12); } else { throw new InvalidOperationException(); } } else if (State == 7) { if (Token.OnSome && Token.Some.OnLeftParen) { Shift(6); } else { Reduce2((u, e) => SyntaxRule.CreateExpr(SyntaxExpr.CreateUnaryOperator(new ProductionUnaryOperator { UnaryOperator = u.UnaryOperator, Expr = e.Expr }))); } } else if (State == 8) { if (!Token.OnSome) { throw MakeInvalidEndOfFile(); } var t = Token.Some; if (t.OnBinaryOperator) { BinaryOperatorStack.Push(t.BinaryOperator); Shift(9); } else if (t.OnRightParen) { Shift(13); } else { throw MakeInvalidSyntaxRule(); } } else if (State == 9) { if (!Token.OnSome) { throw MakeInvalidEndOfFile(); } var t = Token.Some; if (t.OnLiteral) { Shift(1); } else if (t.OnIdentifier) { Shift(2); } else if (t.OnBinaryOperator) { if (t.BinaryOperator.Name == "+" || t.BinaryOperator.Name == "-") { Replace(SyntaxRule.CreateUnaryOperator(new TokenUnaryOperator { Name = t.BinaryOperator.Name })); } else { throw MakeInvalidSyntaxRule(); } } else if (t.OnUnaryOperator) { Shift(3); } else if (t.OnLeftParen) { Shift(4); } else if (t.OnRightParen) { throw MakeInvalidSyntaxRule(); } else if (t.OnComma) { throw MakeInvalidSyntaxRule(); } else if (t.OnExpr) { Shift(14); } else if (t.OnParameterList) { throw MakeInvalidSyntaxRule(); } else if (t.OnNonnullParameterList) { throw MakeInvalidSyntaxRule(); } else { throw new InvalidOperationException(); } } else if (State == 10) { if (Token.OnSome && Token.Some.OnBinaryOperator) { BinaryOperatorStack.Push(Token.Some.BinaryOperator); Shift(9); } else { Reduce1(e => SyntaxRule.CreateNonnullParameterList(SyntaxNonnullParameterList.CreateSingle(new ProductionSingleParameterList { Expr = e.Expr }))); } } else if (State == 11) { if (!Token.OnSome) { throw MakeInvalidEndOfFile(); } var t = Token.Some; if (t.OnRightParen) { Shift(15); } else { throw MakeInvalidSyntaxRule(); } } else if (State == 12) { if (Token.OnSome && Token.Some.OnComma) { Shift(16); } else { Reduce1(n => SyntaxRule.CreateParameterList(SyntaxParameterList.CreateNonnull(new ProductionNonnullParameterList { NonnullParameterList = n.NonnullParameterList }))); } } else if (State == 13) { Reduce3((lp, e, rp) => SyntaxRule.CreateExpr(SyntaxExpr.CreateParen(new ProductionParen { Expr = e.Expr }))); } else if (State == 14) { if (Token.OnSome && Token.Some.OnBinaryOperator) { var sbo = BinaryOperatorStack.Peek(); var bo = Token.Some.BinaryOperator; var sp = GetPriority(sbo); var p = GetPriority(bo); if (p == 3 && p == sp && bo.Name != sbo.Name) { throw MakeInvalidSyntaxRule(); } else if (p >= sp) { Reduce3((le, b, re) => SyntaxRule.CreateExpr(SyntaxExpr.CreateBinaryOperator(new ProductionBinaryOperator { Left = le.Expr, BinaryOperator = b.BinaryOperator, Right = re.Expr }))); BinaryOperatorStack.Pop(); } else { BinaryOperatorStack.Push(Token.Some.BinaryOperator); Shift(9); } } else { Reduce3((le, b, re) => SyntaxRule.CreateExpr(SyntaxExpr.CreateBinaryOperator(new ProductionBinaryOperator { Left = le.Expr, BinaryOperator = b.BinaryOperator, Right = re.Expr }))); BinaryOperatorStack.Pop(); } } else if (State == 15) { Reduce4((i, lp, p, rp) => SyntaxRule.CreateExpr(SyntaxExpr.CreateFunction(new ProductionFunction { Identifier = i.Identifier, ParameterList = p.ParameterList }))); } else if (State == 16) { if (!Token.OnSome) { throw MakeInvalidEndOfFile(); } var t = Token.Some; if (t.OnLiteral) { Shift(1); } else if (t.OnIdentifier) { Shift(2); } else if (t.OnBinaryOperator) { if (t.BinaryOperator.Name == "+" || t.BinaryOperator.Name == "-") { Replace(SyntaxRule.CreateUnaryOperator(new TokenUnaryOperator { Name = t.BinaryOperator.Name })); } else { throw MakeInvalidSyntaxRule(); } } else if (t.OnUnaryOperator) { Shift(3); } else if (t.OnLeftParen) { Shift(4); } else if (t.OnRightParen) { throw MakeInvalidSyntaxRule(); } else if (t.OnComma) { throw MakeInvalidSyntaxRule(); } else if (t.OnExpr) { Shift(17); } else if (t.OnParameterList) { throw MakeInvalidSyntaxRule(); } else if (t.OnNonnullParameterList) { throw MakeInvalidSyntaxRule(); } else { throw new InvalidOperationException(); } } else if (State == 17) { if (Token.OnSome && Token.Some.OnBinaryOperator) { BinaryOperatorStack.Push(Token.Some.BinaryOperator); Shift(9); } else { Reduce3((n, c, e) => SyntaxRule.CreateNonnullParameterList(SyntaxNonnullParameterList.CreateMultiple(new ProductionMultipleParameterList { NonnullParameterList = n.NonnullParameterList, Expr = e.Expr }))); } } else { throw new InvalidOperationException(); } } throw new InvalidOperationException(); }
/// <summary>参数列表</summary> public static SyntaxRule CreateParameterList(SyntaxParameterList Value) { return(new SyntaxRule { _Tag = SyntaxRuleTag.ParameterList, ParameterList = Value }); }