Ejemplo n.º 1
0
        private AstNode CreateNode(ActionRecord reduceAction, SourceSpan sourceSpan, AstNodeList childNodes)
        {
            NonTerminal nonTeminal = reduceAction.NonTerminal;
            AstNode     result;
            AstNodeArgs args = new AstNodeArgs(nonTeminal, sourceSpan, childNodes);

            Type defaultNodeType = _context.Compiler.Data.DefaultNodeType;
            Type ntNodeType      = nonTeminal.NodeType ?? defaultNodeType ?? typeof(AstNode);

            bool isList = nonTeminal.IsSet(TermOptions.IsList);

            if (isList && childNodes.Count > 1 && childNodes[0].Term == nonTeminal)
            {
                result = childNodes[0];
                AstNode newChild = childNodes[childNodes.Count - 1];
                newChild.Parent = result;
                result.ChildNodes.Add(newChild);
                return(result);
            }

            if (nonTeminal.IsSet(TermOptions.IsStarList) && childNodes.Count == 1)
            {
                childNodes = childNodes[0].ChildNodes;
            }

            if (!isList && !nonTeminal.IsSet(TermOptions.IsPunctuation) && childNodes.Count == 1)
            {
                Type childNodeType = childNodes[0].Term.NodeType ?? defaultNodeType ?? typeof(AstNode);
                if (childNodeType == ntNodeType || childNodeType.IsSubclassOf(ntNodeType))
                {
                    return(childNodes[0]);
                }
            }

            result = null;
            if (ntNodeType == typeof(AstNode))
            {
                result = new AstNode(args);
            }
            else
            {
                ConstructorInfo ctor = ntNodeType.GetConstructor(new Type[] { typeof(AstNodeArgs) });
                if (ctor == null)
                {
                    throw new Exception("Failed to located constructor: " + ntNodeType.ToString() + "(AstNodeArgs args)");
                }

                result = (AstNode)ctor.Invoke(new object[] { args });
            }

            return(result);
        }