public bool Visit(DereferenceOperator node)
        {
            if (node.SymType != null)
            {
                return(true);
            }

            node.Expr.Accept(this);

            if (!node.Expr.IsLValue)
            {
                throw new Exception(string.Format(
                                        "({0}, {1}) semantic error: expression '{2}' is not lvalue",
                                        node.Expr.Token.Line, node.Expr.Token.Column, node.Expr.ToString()));
            }

            if (!(node.Expr.SymType is SymPointerType))
            {
                throw new Exception(string.Format(
                                        "({0}, {1}) semantic error: expression '{2}' is not a pointer",
                                        node.Expr.Token.Line, node.Expr.Token.Column, node.Expr.ToString()));
            }

            node.SymType = ((SymPointerType)node.Expr.SymType).ReferencedSymType;
            return(true);
        }
示例#2
0
        public AstPrinterNode Visit(DereferenceOperator node)
        {
            var printer = new AstPrinterNode(node.ToString());

            printer.AddChild(node.Expr.Accept(this));
            return(printer);
        }
        private Expression ParseVariableReference()
        {
            var token = PeekToken();

            AstNode left = ParseIdent();

            if (left == null)
            {
                return(null); // this is not variable ref
            }

            bool breakWhile = false;

            while (!breakWhile)
            {
                token = PeekToken();
                switch (token.Type)
                {
                case TokenType.OpenSquareBracket:
                {
                    NextToken();
                    var paramList = ParseParamList();
                    if (paramList == null || paramList.Count == 0)
                    {
                        throw new Exception(string.Format(
                                                "({0}, {1}) syntax error: indexes expected, but {2} found",
                                                PeekToken().Line, PeekToken().Column, PeekToken().Lexeme));
                    }

                    token = PeekToken();
                    CheckToken(PeekToken().Type, new List <TokenType> {
                            TokenType.CloseSquareBracket
                        },
                               string.Format("({0}, {1}) syntax error: ']' expected, but {2} found",
                                             PeekToken().Line, PeekToken().Column, PeekAndNext().Lexeme));

                    if (!(left is Ident || left is RecordAccess || left is ArrayAccess))
                    {
                        throw new Exception(string.Format(
                                                "({0}, {1}) syntax error: accessing array must be identifier",
                                                left.Token.Line, left.Token.Column, left.Token.Lexeme));
                    }

                    left = new ArrayAccess(left as Expression, paramList);
                    break;
                }

                case TokenType.Dot:
                {
                    NextToken();
                    var field = ParseIdent();
                    if (field == null)
                    {
                        throw new Exception(string.Format(
                                                "({0}, {1}) syntax error: field ident expected, but {2} found",
                                                PeekToken().Line, PeekToken().Column, PeekToken().Lexeme));
                    }

//                        if (!(field is Ident))
//                        {
//                            throw new Exception(string.Format(
//                                "{0}, {1} : syntax error, accessing field must be identifier",
//                                field.Token.Line, field.Token.Column, field.Token.Lexeme));
//                        }

                    left = new RecordAccess(left as Expression, field as Ident);
                    break;
                }

                case TokenType.OpenBracket:
                {
                    token = NextAndPeek();
                    var paramList = ParseParamList();

                    if (paramList == null)
                    {
                        throw new Exception(string.Format(
                                                "({0}, {1}) syntax error: parameters list expected, but {2} found",
                                                PeekToken().Line, PeekToken().Column, PeekToken().Lexeme));
                    }

                    CheckToken(PeekToken().Type, new List <TokenType> {
                            TokenType.CloseBracket
                        },
                               string.Format("({0}, {1}) syntax error: ')' expected, but {2} found",
                                             PeekToken().Line, PeekToken().Column, PeekAndNext().Lexeme));

                    if (!(left is Ident))
                    {
                        throw new Exception(string.Format(
                                                "({0}, {1}) syntax error: accessing field must be identifier",
                                                left.Token.Line, left.Token.Column, left.Token.Lexeme));
                    }

                    left = left.Token.Type == TokenType.Write || left.Token.Type == TokenType.WriteLn
                            ? (AstNode) new WriteFunctionCall((Ident)left, paramList,
                                                              left.Token.Type == TokenType.WriteLn)
                            : new UserFunctionCall((Ident)left, paramList);
                    break;
                }

                case TokenType.Carriage:
                {
                    if (left.NodeType == AstNodeType.DereferenceOperator)
                    {
                        throw new Exception(string.Format("({0}, {1}) syntax error: double carriage found",
                                                          PeekToken().Line, PeekToken().Column, PeekToken().Lexeme));
                    }

                    var carriageToken = PeekAndNext();
                    left = new DereferenceOperator(carriageToken, left as Expression);
                    break;
                }

                default:
                {
                    breakWhile = true;
                    break;
                }
                }
            }

            return(left as Expression);
        }