Ejemplo n.º 1
0
 public AstNodeArgs(BnfTerm term, CompilerContext context, SourceSpan span, AstNodeList childNodes)
 {
     Context = context;
       Term = term;
       Span = span;
       ChildNodes = childNodes;
 }
Ejemplo n.º 2
0
        private void ExecuteReduceAction(ActionRecord action)
        {
            ParserState oldState = _currentState;
              int popCnt = action.PopCount;

              //Get new node's child nodes - these are nodes being popped from the stack
              AstNodeList childNodes = new AstNodeList();
              for (int i = 0; i < action.PopCount; i++) {
            AstNode child = Stack[Stack.Count - popCnt + i].Node;
            if (!child.Term.IsSet(TermOptions.IsPunctuation))
              childNodes.Add(child);
              }
              //recover state, location and pop the stack
              SourceSpan newNodeSpan;
              if (popCnt == 0) {
            newNodeSpan = new SourceSpan(_currentToken.Location, 0);
              } else {
            SourceLocation firstPopLoc = Stack[Stack.Count - popCnt].Node.Location;
            int lastPopEndPos = Stack[Stack.Count - 1].Node.Span.EndPos;
            newNodeSpan = new SourceSpan(firstPopLoc, lastPopEndPos - firstPopLoc.Position);
            _currentState = Stack[Stack.Count - popCnt].State;
            Stack.Pop(popCnt);
              }
              //Create new node
              AstNode node = CreateNode(action, newNodeSpan, childNodes);
              // Push node/current state into the stack
              Stack.Push(node, _currentState);
              //switch to new state
              ActionRecord gotoAction;
              if (_currentState.Actions.TryGetValue(action.NonTerminal.Key, out gotoAction)) {
            _currentState = gotoAction.NewState;
              } else
            //should never happen
            throw new CompilerException( string.Format("Cannot find transition for input {0}; state: {1}, popped state: {2}",
              action.NonTerminal, oldState, _currentState));
        }
Ejemplo n.º 3
0
        private AstNode CreateNode(ActionRecord reduceAction, SourceSpan sourceSpan, AstNodeList childNodes)
        {
            NonTerminal nt = reduceAction.NonTerminal;
              AstNode result;

              AstNodeArgs args = new AstNodeArgs(nt, _context, sourceSpan, childNodes);
              result = nt.InvokeNodeCreator(args);
              if (result != null) return result;

              Type defaultNodeType = _context.Compiler.Grammar.DefaultNodeType;
              Type ntNodeType = nt.NodeType ?? defaultNodeType ?? typeof(AstNode);

              // Check if NonTerminal is a list
              // List nodes are produced by .Plus() or .Star() methods of BnfElement
              // In this case, we have a left-recursive list formation production:
              //     ntList -> ntList + delim? + ntElem
              //  We check if we have already created the list node for ntList (in the first child);
              //  if yes, we use this child as a result directly, without creating new list node.
              //  The other incoming child - the last one - is a new list member;
              // we simply add it to child list of the result ntList node. Optional "delim" node is simply thrown away.
              bool isList = nt.IsSet(TermOptions.IsList);
              if (isList && childNodes.Count > 1 && childNodes[0].Term == nt) {
            result = childNodes[0];
            AstNode newChild = childNodes[childNodes.Count - 1];
            newChild.Parent = result;
            result.ChildNodes.Add(newChild);
            return result;
              }
              //Check for StarList produced by MakeStarList; in this case the production is:  ntList -> Empty | Elem+
              // where Elem+ is non-empty list of elements. The child list we are actually interested in is one-level lower
              if (nt.IsSet(TermOptions.IsStarList) && childNodes.Count == 1) {
            childNodes = childNodes[0].ChildNodes;
              }
              // Check for "node-bubbling" case. For identity productions like
              //   A -> B
              // the child node B is usually a subclass of node A,
              // so child node B can be used directly in place of the A. So we simply return child node as a result.
              // TODO: probably need a grammar option to enable/disable this behavior explicitly
              if (!isList && !nt.IsSet(TermOptions.IsPunctuation) && childNodes.Count == 1) {
            Type childNodeType = childNodes[0].Term.NodeType ?? defaultNodeType ?? typeof(AstNode);
            if (childNodeType == ntNodeType || childNodeType.IsSubclassOf(ntNodeType))
              return childNodes[0];
              }
              // Try using Grammar's CreateNode method
              result = Data.Grammar.CreateNode(_context, reduceAction, sourceSpan, childNodes);
              if (result == null) {
            //Finally create node directly. For perf reasons we try using "new" for AstNode type (faster), and
            // activator for all custom types (slower)
            if (ntNodeType == typeof(AstNode))
              result = new AstNode(args);
            else
            #if PocketPC || SILVERLIGHT
            {
              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 });
            }
            #else
            {
              result = (AstNode)Activator.CreateInstance(ntNodeType, args);
            }
            #endif
              }
              if (result != null)
            nt.OnNodeCreated(result);
              return result;
        }
Ejemplo n.º 4
0
 // Override this method in language grammar if you want a custom node creation mechanism.
 public virtual AstNode CreateNode(CompilerContext context, ActionRecord reduceAction, 
                               SourceSpan sourceSpan, AstNodeList childNodes)
 {
     return null;
 }
Ejemplo n.º 5
0
 // Override this method in language grammar if you want a custom node creation mechanism.
 public virtual AstNode CreateNode(CompilerContext context, ActionRecord reduceAction,
                                   SourceSpan sourceSpan, AstNodeList childNodes)
 {
     return(null);
 }