Exemple #1
0
        private static TypeSpec TranslateTypeSpec(OS.TypeSpec t, Text Text, Dictionary <Object, TextRange> InnerPositions, Dictionary <Object, TextRange> Positions)
        {
            if (t.OnTypeRef)
            {
                var r = TypeSpec.CreateTypeRef((TypeRef)(t.TypeRef.VersionedName()));
                if (InnerPositions.ContainsKey(t))
                {
                    Positions.Add(r, InnerPositions[t]);
                }
                return(r);
            }
            else if (t.OnGenericTypeSpec && t.GenericTypeSpec.TypeSpec.OnTypeRef && t.GenericTypeSpec.TypeSpec.TypeRef.NameMatches("Optional") && t.GenericTypeSpec.ParameterValues.Count == 1)
            {
                var Parameter = t.GenericTypeSpec.ParameterValues.Single();
                var InnerType = TranslateTypeSpec(Parameter, Text, InnerPositions, Positions);
                if (InnerType.OnTypeRef)
                {
                    var r = TypeSpec.CreateOptional(InnerType.TypeRef);
                    if (InnerPositions.ContainsKey(t))
                    {
                        Positions.Add(r, InnerPositions[t]);
                    }
                    return(r);
                }
            }
            else if (t.OnGenericTypeSpec && t.GenericTypeSpec.TypeSpec.OnTypeRef && t.GenericTypeSpec.TypeSpec.TypeRef.NameMatches("List") && t.GenericTypeSpec.ParameterValues.Count == 1)
            {
                var Parameter = t.GenericTypeSpec.ParameterValues.Single();
                if (Parameter.OnTypeRef && Parameter.TypeRef.NameMatches("Byte"))
                {
                    var r = TypeSpec.CreateTypeRef((TypeRef)("Binary"));
                    if (InnerPositions.ContainsKey(t))
                    {
                        Positions.Add(r, InnerPositions[t]);
                    }
                    return(r);
                }
                else
                {
                    var InnerType = TranslateTypeSpec(Parameter, Text, InnerPositions, Positions);
                    if (InnerType.OnTypeRef)
                    {
                        var r = TypeSpec.CreateList(InnerType.TypeRef);
                        if (InnerPositions.ContainsKey(t))
                        {
                            Positions.Add(r, InnerPositions[t]);
                        }
                        return(r);
                    }
                }
            }
            var oRange    = InnerPositions.ContainsKey(t) ? InnerPositions[t] : TreeFormat.Optional <TextRange> .Empty;
            var FileRange = new FileTextRange {
                Text = Text, Range = oRange
            };

            throw new InvalidEvaluationException("InvalidTypeSpec", FileRange, t);
        }
 private PrimitiveType ParseType(String e, FileTextRange r)
 {
     if (e.Equals("Boolean", StringComparison.Ordinal))
     {
         return(PrimitiveType.Boolean);
     }
     if (e.Equals("Int", StringComparison.Ordinal))
     {
         return(PrimitiveType.Int);
     }
     if (e.Equals("Real", StringComparison.Ordinal))
     {
         return(PrimitiveType.Real);
     }
     throw new InvalidSyntaxException("TypeInvalid: " + e, r);
 }
Exemple #3
0
        private static TypeSpec ParseTypeSpec(TFSemantics.Node TypeNode, ISemanticsNodeMaker nm, Dictionary <Object, TextRange> Positions)
        {
            var TypeSpecString = GetLeafNodeValue(TypeNode, nm, "InvalidTypeSpec");
            var InnerPositions = new Dictionary <Object, TextRange>();
            var ts             = OS.TypeParser.ParseTypeSpec
                                 (
                TypeSpecString,
                (o, Start, End) =>
            {
                var oRange = nm.GetRange(TypeNode);
                if (oRange.OnSome)
                {
                    var Range     = oRange.Value;
                    var TypeRange = new TextRange {
                        Start = nm.Text.Calc(Range.Start, Start), End = nm.Text.Calc(Range.Start, End)
                    };
                    InnerPositions.Add(o, TypeRange);
                }
            },
                Index =>
            {
                var FileRange = TreeFormat.Optional <FileTextRange> .Empty;
                var oRange    = nm.GetRange(TypeNode);
                if (oRange.OnSome)
                {
                    var Range = oRange.Value;
                    FileRange = new FileTextRange {
                        Text = nm.Text, Range = new TextRange {
                            Start = nm.Text.Calc(Range.Start, Index), End = nm.Text.Calc(Range.Start, Index + 1)
                        }
                    };
                }
                return(new InvalidTokenException("InvalidChar", FileRange, TypeSpecString.Substring(Index, 1)));
            }
                                 );

            return(TranslateTypeSpec(ts, nm.Text, InnerPositions, Positions));
        }
Exemple #4
0
        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();
        }