Example #1
0
        }                                    // set during AST construction

        #region implemented abstract members of Node

        /// <summary>
        /// Resolve type defined by this typeExpression. Type Expression must be given in reversed order.
        /// </summary>
        /// <returns>The resolved type.</returns>
        /// <param name="typeExpr">Enumerator of reversed type expresion enumeration.</param>
        public static TypeNode RecursiveResolveArrayType <TSymbol>(IEnumerator <IParseTree <TSymbol> > typeExpr) where TSymbol : ISymbol <TSymbol>
        {
            bool isMutable = ASTBuilder.EatSymbol("mutable", typeExpr);

            if (ASTBuilder.EatSymbol("]", typeExpr))   // if ] is present then create ArrayType
            {
                var resType = new ArrayTypeNode();
                resType.IsConstant  = !isMutable;
                resType.IsFixedSize = false;             // we initialize all arrays as dynamic size
                if (ASTBuilder.EatSymbol("[", typeExpr)) // opening bracket, no length expression
                {
                    resType.LengthExpression = null;
                }
                else     // length expression present
                {
                    resType.LengthExpression = ExpressionNode.GetExpressionNode(typeExpr.Current);
                    typeExpr.MoveNext();
                    Debug.Assert(ASTBuilder.EatSymbol("[", typeExpr)); // eat opening bracket
                }
                resType.ElementType = RecursiveResolveArrayType(typeExpr);
                return(resType);
            }
            else
            {
                var resType = new NamedTypeNode();
                resType.BuildNode(typeExpr.Current);
                resType.IsConstant = !isMutable;
                return(resType);
            }
        }
 public static ExpressionNode ResolveOperatorExpression <TSymbol>(IParseTree <TSymbol> parseTree, int opLevel) where TSymbol : ISymbol <TSymbol>
 {
     if (opLevel > OP_BOTTOM_LEVEL)
     {
         // these part proceeds op from level 15 to 5
         bool isLeft = ASTBuilder.IsLeftOperator(parseTree.Symbol);
         // get childrens connected by operators (one level lower)
         var childs = isLeft ?
                      ASTBuilder.Children(parseTree).Reverse().GetEnumerator() : // if left-to-right then reverse arguments
                      ASTBuilder.Children(parseTree).GetEnumerator();
         Debug.Assert(childs.MoveNext());                                        // set enumerator to the first element (must be present)
         return(ParseBinOperator(childs, opLevel - 1, isLeft));
     }
     else
     {
         // continue parsing lower level expressions
         Debug.Assert(opLevel == OP_BOTTOM_LEVEL);    // op level must be 4
         var node = ASTBuilder.FirstChild(parseTree); // Operator4Expression -> Operator3Expression
         // Operator3Expression -> (prefix_operator)* Operator2Expression
         var childs = ASTBuilder.Children(node).Reverse().GetEnumerator();
         Debug.Assert(childs.MoveNext());
         var op2       = childs.Current; // last child -> Operator2Expression
         var op2Childs = ASTBuilder.RevChildrenEnumerator(op2);
         Debug.Assert(op2Childs.MoveNext());
         return(AddPrefixOperators(3, ParseOperator2(op2Childs), childs));
     }
 }
        }                                         // set during AST construction

        #region implemented abstract members of Node

        public override void BuildNode <TSymbol>(IParseTree <TSymbol> parseTree)
        {
            // LoopControl -> ("break" | "continue") (Expression DecimalNumberLiteral?)?
            var childs = ASTBuilder.ChildrenArray(parseTree);

            Debug.Assert(childs.Length >= 1);
            switch (childs[0].Fragment.GetOriginText())
            {
            case "break":
                Mode = LoopControlMode.LCM_BREAK;
                break;

            case "continue":
                Mode = LoopControlMode.LCM_CONTINUE;
                break;
            }
            if (childs.Length >= 2)
            {
                Value = ExpressionNode.GetExpressionNode(childs[1]);
            }
            if (childs.Length == 3)
            {
                Depth = int.Parse(childs[2].Fragment.GetOriginText());
            }
        }
Example #4
0
 public override void BuildNode <TSymbol>(IParseTree <TSymbol> parseTree)
 {
     // DecimalNumberLiteral ->  DecimalNumberLiteralToken
     // CharacterLiteral -> CharacterLiteralToken
     // BooleanLiteral -> BooleanLiteralToken
     Value = ASTBuilder.FirstChild(parseTree).Fragment.GetOriginText(); // fill only value - type was set during construction
 }
Example #5
0
        public static ConstNode GetConstNode <TSymbol>(IParseTree <TSymbol> parseTree) where TSymbol : ISymbol <TSymbol>
        {
            // one of: DecimalNumberLiteral | CharacterLiteral | StringLiteral | BooleanLiteral
            TypeNode type;

            switch (ASTBuilder.GetName(parseTree.Symbol))
            {
            case "DecimalNumberLiteral":
                type = NamedTypeNode.IntType(true);
                break;

            case "CharacterLiteral":
                type = NamedTypeNode.CharType(true);
                break;

            case "StringLiteral":
                throw new NotImplementedException();     // TODO: strings implementation

            case "BooleanLiteral":
                type = NamedTypeNode.BoolType(true);
                break;

            default:
                throw new System.ArgumentException();
            }
            return(new AtomNode(type));
        }
        public override void BuildNode <TSymbol> (IParseTree <TSymbol> parseTree)
        {
            var arr = ASTBuilder.ChildrenArray(parseTree);

            FieldName = arr [0].Fragment.GetOriginText();
            Value     = ExpressionNode.GetExpressionNode(arr [2]);
        }
Example #7
0
        }                                          // set during AST construction

        #region implemented abstract members of Node

        // RecordFieldDefinition.SetProduction(ObjectDeclaration * ";");
        // ObjectDeclaration.SetProduction(TypeSpecifier * ObjectName);
        public override void BuildNode <TSymbol>(IParseTree <TSymbol> parseTree)
        {
            IParseTree <TSymbol>[] childs = ASTBuilder.ChildrenArray(parseTree);
            // type name
            Debug.Assert(childs.Length == 2);
            Type = TypeNode.GetTypeNode(childs[0]);             // type - arg 0
            Name = childs[1].Fragment.GetOriginText();          // name - arg 1
        }
Example #8
0
        // TypeSpecifier -> (TypeName * ("mutable".Optional() * "\\[" * Expression.Optional * "\\]").Star * "mutable".Optional());
        public static TypeNode GetTypeNode <TSymbol>(IParseTree <TSymbol> parseTree) where TSymbol : ISymbol <TSymbol>
        {
            var node   = ASTBuilder.AsBranch(parseTree);
            var childs = node.Children.Reverse().GetEnumerator();

            Debug.Assert(childs.MoveNext());
            return(RecursiveResolveArrayType(childs));
        }
        }                                                             // name resolution

        #region implemented abstract members of Node

        public override void BuildNode <TSymbol> (IParseTree <TSymbol> parseTree)
        {
            // <recordName> [ <field> ]
            var children = ASTBuilder.ChildrenArray(parseTree);

            RecordName = children [0].Fragment.GetOriginText();
            Field      = children [2].Fragment.GetOriginText();
        }
        public override void BuildNode <TSymbol>(IParseTree <TSymbol> parseTree)
        {
            // ObjectDefinition -> TypeSpecifier ObjectName "=" Expression
            var childs = ASTBuilder.ChildrenArray(parseTree);

            Debug.Assert(childs.Length == 4);
            Type  = TypeNode.GetTypeNode(childs[0]);             // type - arg 0
            Name  = childs[1].Fragment.GetOriginText();          // name - arg 1
            Value = ExpressionNode.GetExpressionNode(childs[3]); // value - arg 3
        }
 public override void BuildNode <TSymbol> (IParseTree <TSymbol> parseTree)
 {
     Console.WriteLine("Build ast: " + parseTree);
     IParseTree <TSymbol>[] childs = ASTBuilder.ChildrenArray(parseTree);
     // name { fields }
     Debug.Assert(childs.Length == 4);
     // name from arg 0
     Name = TypeNode.GetTypeNode(childs[0]);
     // fields from arg 2
     Fields = GetFields(childs[2]);
 }
        public override void BuildNode <TSymbol> (IParseTree <TSymbol> parseTree)
        {
            // <type> <name> { <fields> }
            var children = ASTBuilder.ChildrenArray(parseTree);

            Debug.Assert(children.Length == 5);

            Type   = TypeNode.GetTypeNode(children[0]);    // type - arg 0
            Name   = children[1].Fragment.GetOriginText(); // name - arg 1
            Fields = GetFields(children [3]);              // fields - arg 3
        }
Example #13
0
        public override void BuildNode <TSymbol>(IParseTree <TSymbol> parseTree)
        {
            // IfExpression -> "if" Expression Expression ("else" Expression)?
            var childs = ASTBuilder.ChildrenArray(parseTree);

            Debug.Assert(childs.Length >= 3);
            Condition = ExpressionNode.GetExpressionNode(childs[1]);
            Then      = ExpressionNode.GetExpressionNode(childs[2]);
            if (childs.Length == 5)
            {
                Else = ExpressionNode.GetExpressionNode(childs[4]);
            }
        }
        }                                                                           // set during AST construction

        #region implemented abstract members of Node

        public IEnumerable <RecordVariableFieldDefNode> GetFields <TSymbol> (IParseTree <TSymbol> parseTree) where TSymbol : ISymbol <TSymbol>
        {
            var lst    = new LinkedList <RecordVariableFieldDefNode> ();
            var childs = ASTBuilder.ChildrenEnumerator(parseTree);

            while (childs.MoveNext())
            {
                var v = new RecordVariableFieldDefNode();
                v.BuildNode(childs.Current);
                lst.AddLast(v);
                childs.MoveNext();                 // skip ',' if present
            }
            return(lst);
        }
Example #15
0
        // ----- Methods -----

        #region implemented abstract members of Node

        private IEnumerable <VariableDeclNode> GetParameters <TSymbol>(IParseTree <TSymbol> parseTree) where TSymbol : ISymbol <TSymbol>
        {
            var parList = new LinkedList <VariableDeclNode>();
            var childs  = ASTBuilder.ChildrenEnumerator(parseTree);

            while (childs.MoveNext())
            {
                var par = new VariableDeclNode();
                par.BuildNode(childs.Current);
                parList.AddLast(par);
                childs.MoveNext(); // skip ',' if present
            }
            return(parList);
        }
Example #16
0
 public override void BuildNode <TSymbol>(IParseTree <TSymbol> parseTree)
 {
     IParseTree <TSymbol>[] childs = ASTBuilder.ChildrenArray(parseTree);
     // name ( params ) -> type expr
     Debug.Assert(childs.Length == 7);
     // name from arg 0
     Name = childs[0].Fragment.GetOriginText();
     // parameters from arg 2
     Parameters = GetParameters(childs[2]);
     // type from arg 5
     ResultType = TypeNode.GetTypeNode(childs[5]);
     // body from arg 6
     Body = ExpressionNode.GetExpressionNode(childs[6]);
 }
        static IEnumerable <RecordTypeFieldDeclarationNode> GetFields <TSymbol>(IParseTree <TSymbol> parseTree)
            where TSymbol : ISymbol <TSymbol>
        {
            var lst    = new LinkedList <RecordTypeFieldDeclarationNode>();
            var childs = ASTBuilder.ChildrenEnumerator(parseTree);

            while (childs.MoveNext())
            {
                var objectDefinition = ASTBuilder.ChildrenArray(childs.Current) [0];
                var fld = new RecordTypeFieldDeclarationNode();
                fld.BuildNode(objectDefinition);
                lst.AddLast(fld);
            }
            return(lst);
        }
        /// <summary>
        /// Resolve Expression from ParseTree. Main method.
        /// </summary>
        public static ExpressionNode GetExpressionNode <TSymbol>(IParseTree <TSymbol> parseTree) where TSymbol : ISymbol <TSymbol>
        {
            var node = ASTBuilder.FirstChild(parseTree);             // Expression -> RecordVariableDefinitionExpression | RecordFieldAccessExpression | OperatorExpression

            if (ASTBuilder.GetName(node.Symbol) == "RecordVariableDefinitionExpression")
            {
                var nod = new RecordVariableDefNode();
                nod.BuildNode(node);
                return(nod);
            }

            if (ASTBuilder.GetName(node.Symbol) == "RecordFieldAccessExpression")
            {
                var nod = new RecordVariableFieldUseNode();
                nod.BuildNode(node);
                return(nod);
            }

            node = ASTBuilder.FirstChild(node);                                  // OperatorExpression -> Operator19Expression
            node = ASTBuilder.FirstChild(node);                                  // Operator19Expression -> ObjectDefinitionExpression | Operator18Expression
            if (ASTBuilder.GetName(node.Symbol) == "ObjectDefinitionExpression") // ObjectDefinition
            {
                var defNode = new VariableDefNode();
                defNode.BuildNode(node);
                return(defNode);
            }
            // Operator18Expression
            node = ASTBuilder.FirstChild(node); // IfExpression | WhileExpression | Operator17Expression
            switch (ASTBuilder.GetName(node.Symbol))
            {
            case "IfExpression":
                var ifNode = new IfNode();
                ifNode.BuildNode(node);
                return(ifNode);

            case "WhileExpression":
                var whileNode = new WhileNode();
                whileNode.BuildNode(node);
                return(whileNode);

            default:     // default - Operator17Expression
                break;
            }
            node = ASTBuilder.FirstChild(node);          // Operator17Expression -> Operator16Expression
            node = ASTBuilder.FirstChild(node);          // Operator16Expression -> Operator15Expression
            return(ResolveOperatorExpression(node, 15)); // node is operator 15
        }
Example #19
0
        }                                                         // set during AST construction

        #region implemented abstract members of Node

        public override void BuildNode <TSymbol>(IParseTree <TSymbol> parseTree)
        {
            // Block -> "{" (Expression ";")* "}"
            var childs = ASTBuilder.ChildrenEnumerator(parseTree);

            childs.MoveNext();               // go to "{"
            Debug.Assert(childs.MoveNext()); // enter the brackets
            var elems = new List <ExpressionNode>();

            while (!ASTBuilder.EatSymbol("}", childs)) // collect expressions until closing "}"
            {
                elems.Add(ExpressionNode.GetExpressionNode(childs.Current));
                childs.MoveNext();                               // go to the next symbol
                Debug.Assert(ASTBuilder.EatSymbol(";", childs)); // it must be ";"
            }
            Elements = elems;
        }
        public static ExpressionNode ResolveAtomicExpression <TSymbol>(IParseTree <TSymbol> parseTree) where TSymbol : ISymbol <TSymbol>
        {
            // AtomicExpression -> BlockExpression | ObjectDefinitionExpression | ArrayLiteralExpression | ObjectUseExpression |
            //                     IfExpression | WhileExpression | LoopControlExpression
            var            node = ASTBuilder.FirstChild(parseTree); // AtomicExpression -> one of available symbols
            ExpressionNode atomic;

            switch (ASTBuilder.GetName(node.Symbol))
            {
            case "BlockExpression":
                atomic = new BlockExpressionNode();
                break;

            case "ArrayLiteralExpression":
                throw new System.NotImplementedException();     // TODO: arrays implementation

            case "ObjectUseExpression":
                // ObjectUseExpression -> ObjectName | Literals
                node = ASTBuilder.FirstChild(node);
                if (node.Symbol.IsTerminal)       // ObjectName
                {
                    atomic = new VariableUseNode();
                }
                else                                      // Literals
                {
                    node   = ASTBuilder.FirstChild(node); // Literals -> one of available literals
                    atomic = ConstNode.GetConstNode(node);
                }
                break;

            case "LoopControlExpression":
                atomic = new LoopControlNode();
                break;

            default:
                throw new System.ArgumentException();
            }
            atomic.BuildNode(node);
            return(atomic);
        }
Example #21
0
        // ----- Methods -----

        #region implemented abstract members of Node

        // Program -> (Function|Record)* Eof
        public override void BuildNode <TSymbol>(IParseTree <TSymbol> parseTree)
        {
            var childs = ASTBuilder.ChildrenArray(parseTree);

            for (int i = 0; i < childs.Length - 1; i++) // skip last child - it is EOF
            {
                switch (ASTBuilder.GetName(childs [i].Symbol))
                {
                case "RecordTypeDeclaration":
                    var recordNode = new RecordTypeDeclarationNode();
                    recordNode.BuildNode(childs [i]);
                    records.AddLast(recordNode);
                    break;

                default:
                    var funNode = new FunctionDefinitionNode();
                    funNode.BuildNode(childs [i]);
                    functions.AddLast(funNode);
                    break;
                }
            }
        }
        /// <summary>
        /// Parse one line expression with ++ -- (postfix), function call, array subscript, slice subscript operators.
        /// Enumerator must be given with reversed ordering of arguments. This corresponds to Operator2Expression from Grammar.
        /// </summary>
        public static ExpressionNode ParseOperator2 <TSymbol>(IEnumerator <IParseTree <TSymbol> > opExpr) where TSymbol : ISymbol <TSymbol>
        {
            // O2 -> O1 (     "++" | "--"
            //           |    "(" (E ",")* E? ")"
            //           |    "[" E "]"
            //           |    "[" E? ".." E? "]"
            //          )*
            if (opExpr.Current.Symbol.IsTerminal)
            {
                string curText = ASTBuilder.EatTerminal(opExpr);
                switch (curText)
                {
                case "++":
                case "--":
                    return(OperatorNode.BuildUnaryOperator(2, curText, ParseOperator2(opExpr)));

                case ")":
                    var args = new LinkedList <ExpressionNode>();
                    while (!ASTBuilder.EatSymbol("(", opExpr))
                    {
                        ASTBuilder.EatSymbol(",", opExpr); // eat ',' before arg - f(x,y,z,) is also possible
                        args.AddFirst(GetExpressionNode(opExpr.Current));
                        opExpr.MoveNext();                 // move to next param with ','
                    }
                    var res = new FunctionCallNode();
                    res.Arguments = new List <ExpressionNode>(args);
                    // TODO: can something return a 'pointer' to function which we can call to execute?
                    res.Name = opExpr.Current.Fragment.GetOriginText();
                    return(res);

                case "]":
                    var  toExpr   = ASTBuilder.EatNonTerminal(opExpr);  // slice to or index
                    bool isSlice  = ASTBuilder.EatSymbol("..", opExpr);
                    var  fromExpr = ASTBuilder.EatNonTerminal(opExpr);
                    Debug.Assert(ASTBuilder.EatSymbol("[", opExpr));
                    if (isSlice)     // slice subscript
                    {
                        return(SliceNode.CreateSliceNode(ParseOperator2(opExpr),
                                                         GetExpressionOrNull(fromExpr), GetExpressionOrNull(toExpr)));
                    }
                    else     // array subscript
                    {
                        return(ElementNode.Create(ParseOperator2(opExpr), GetExpressionNode(toExpr)));
                    }

                default:
                    Debug.Assert(false);
                    break;
                }
            }
            else // non-terminal -> Operator1Expression
            {
                var op1 = opExpr.Current;
                Debug.Assert(!opExpr.MoveNext());      // it must be final symbol in this enumeration
                var node = ASTBuilder.FirstChild(op1); // Operator1Expression -> Operator0Expression
                // Operator0Expression -> AtomicExpression | "(" Expression ")";
                var childs = ASTBuilder.ChildrenEnumerator(node);
                Debug.Assert(childs.MoveNext());
                if (ASTBuilder.EatSymbol("(", childs))
                {
                    return(GetExpressionNode(childs.Current)); // Expression
                }
                else // proceed with AtomicExpression
                {
                    return(ResolveAtomicExpression(childs.Current));
                }
            }
            return(null);
        }