Example #1
0
        public AstNode Parse(CompilerContext context, IEnumerable <TokenAst> tokenStream)
        {
            _context = context;
            Reset();
            _input = tokenStream.GetEnumerator();
            NextToken();

            while (true)
            {
                if (_currentState == Data.FinalState)
                {
                    AstNode result = _stack[0].Node;
                    _stack.Reset();
                    return(result);
                }

                if (_currentToken.Terminal.Category == TokenCategory.Error)
                {
                    ReportScannerError();
                    return(null);
                }

                ActionRecord action = GetCurrentAction();
                if (action == null)
                {
                    ReportParserError();
                    return(null);
                }

                //TODO: perform conflict resolving
                //if (action.HasConflict())

                switch (action.ActionType)
                {
                case ParserActionType.Operator:
                    if (GetActionTypeForOperation(_currentToken) == ParserActionType.Shift)
                    {
                        goto case ParserActionType.Shift;
                    }
                    else
                    {
                        goto case ParserActionType.Reduce;
                    }

                case ParserActionType.Shift:
                    ExecuteShiftAction(action);
                    break;

                case ParserActionType.Reduce:
                    ExecuteReduceAction(action);
                    break;
                }
            }
        }
Example #2
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);
        }
Example #3
0
        private void ExecuteReduceAction(ActionRecord action)
        {
            ParserState oldState = _currentState;
            int         popCnt   = action.PopCount;

            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);
                }
            }

            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);
            }

            AstNode node = CreateNode(action, newNodeSpan, childNodes);

            _stack.Push(node, _currentState);

            ActionRecord gotoAction;

            if (_currentState.Actions.TryGetValue(action.NonTerminal.Key, out gotoAction))
            {
                _currentState = gotoAction.NewState;
            }
            else
            {
                throw new CompilerException(string.Format("Cannot find transition for input {0}; state: {1}, popped state: {2}",
                                                          action.NonTerminal, oldState, _currentState));
            }
        }
Example #4
0
        private ActionRecord GetCurrentAction()
        {
            ActionRecord action = null;

            if (_currentToken.MatchByValue)
            {
                if (_currentState.Actions.TryGetValue(_currentToken.Text, out action))
                {
                    return(action);
                }
            }

            if (_currentToken.MatchByType && _currentState.Actions.TryGetValue(_currentToken.Terminal.Key, out action))
            {
                return(action);
            }

            return(null);
        }
Example #5
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;
    }
Example #6
0
    private void ExecuteReduceAction(ActionRecord action)
    {
      ParserState oldState = _currentState;
      int popCnt = action.PopCount;

      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);
      }

      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);
      }
      
      AstNode node = CreateNode(action, newNodeSpan, childNodes);
      _stack.Push(node, _currentState);

      ActionRecord gotoAction;
      if (_currentState.Actions.TryGetValue(action.NonTerminal.Key, out gotoAction))
      {
        _currentState = gotoAction.NewState;
      }
      else
        throw new CompilerException(string.Format("Cannot find transition for input {0}; state: {1}, popped state: {2}",
              action.NonTerminal, oldState, _currentState));
    }
Example #7
0
 private void ExecuteShiftAction(ActionRecord action)
 {
   _stack.Push(_currentToken, _currentState);
   _currentState = action.NewState;
   NextToken();
 }
Example #8
0
 private void ExecuteShiftAction(ActionRecord action)
 {
     _stack.Push(_currentToken, _currentState);
     _currentState = action.NewState;
     NextToken();
 }