private ICodeNode ParseSimpleExpression(Token token)
        {
            TokenType signType = null;  // type of leading sign (if any)

            // Look for a leading + or - sign.
            TokenType tokenType = token.type;

            if ((tokenType == PascalTokenType.PLUS) || (tokenType == PascalTokenType.MINUS))
            {
                signType = tokenType;
                token    = NextToken(); // consume the + or -
            }

            // Parse a term and make the root of its tree the root node.
            ICodeNode rootNode = ParseTerm(token);

            // Was there a leading - sign?
            if (signType == PascalTokenType.MINUS)
            {
                // Create a NEGATE node and adopt the current tree
                // as its child. The NEGATE node becomes the new root node.
                ICodeNode negateNode = ICodeFactory.CreateICodeNode(ICodeNodeTypeImplementation.NEGATE);
                negateNode.AddChild(rootNode);
                rootNode = negateNode;
            }

            token     = CurrentToken();
            tokenType = token.type;

            // Loop over additive operators.
            while (ADD_OPS.Contains(tokenType))
            {
                // Create a new operator node and adopt the current tree
                // as its first child.
                ICodeNodeType nodeType = ADD_OPS_OPS_MAP[(PascalTokenType)tokenType];
                ICodeNode     opNode   = ICodeFactory.CreateICodeNode(nodeType);
                opNode.AddChild(rootNode);

                token = NextToken();  // consume the operator

                // Parse another term.  The operator node adopts
                // the term's tree as its second child.
                opNode.AddChild(ParseTerm(token));

                // The operator node becomes the new root node.
                rootNode = opNode;

                token     = CurrentToken();
                tokenType = token.type;
            }

            return(rootNode);
        }
Ejemplo n.º 2
0
        // Parse a statement list.
        protected internal void ParseList(Token token, ICodeNode parentNode, PascalTokenType terminator, PascalErrorCode errorCode)
        {
            // Loop to parse each statement until the END token or the end of the source file.
            while (!(token is EofToken) && (token.type != terminator))
            {
                // Parse a statement.  The parent node adopts the statement node.
                ICodeNode statementNode = Parse(token);
                parentNode.AddChild(statementNode);

                token = CurrentToken();
                TokenType tokenType = token.type;

                // Look for semicolon between statements.
                if (tokenType == PascalTokenType.SEMICOLON)
                    token = NextToken();

                // If at the start of the next assignment statement, then missing a semicolon.
                else if (tokenType == PascalTokenType.IDENTIFIER)
                    errorHandler.flag(token, PascalErrorCode.MISSING_SEMICOLON, this);

                else if (tokenType != terminator)
                {
                    errorHandler.flag(token, PascalErrorCode.UNEXPECTED_TOKEN, this);
                    token = NextToken();
                }
            }

            if (token.type == terminator)
                token = NextToken();
            else
                errorHandler.flag(token, errorCode, this);
        }
        private ICodeNode ParseExpression(Token token)
        {
            ICodeNode rootNode = ParseSimpleExpression(token);

            token = CurrentToken();
            PascalTokenType tokenType = (PascalTokenType)token.type; // TokenType in original Java

            // Look for relational operator
            if (REL_OPS.Contains(tokenType))
            {
                // Create a new operator node and adopt the current tree as its first child.
                ICodeNodeType nodeType = REL_OPS_MAP[tokenType];
                ICodeNode     opNode   = ICodeFactory.CreateICodeNode(nodeType);
                opNode.AddChild(rootNode);

                token = NextToken();
                opNode.AddChild(ParseSimpleExpression(token));
                rootNode = opNode;
            }

            return(rootNode);
        }
        public override ICodeNode Parse(Token token)
        {
            // Create the ASSIGN node.
            ICodeNode assignNode = ICodeFactory.CreateICodeNode(ICodeNodeTypeImplementation.ASSIGN);

            string           targetName = token.text.ToLower();
            SymbolTableEntry targetID   = symbolTableStack.Lookup(targetName);

            if (targetID == null)
            {
                targetID = symbolTableStack.EnterLocal(targetName);
            }

            targetID.AppendLineNumber(token.lineNumber);
            token = NextToken();

            ICodeNode variableNode = ICodeFactory.CreateICodeNode(ICodeNodeTypeImplementation.VARIABLE);

            variableNode.SetAttribute(ICodeKeyImplementation.ID, targetID);
            assignNode.AddChild(variableNode);

            if (token.type == PascalTokenType.COLON_EQUALS)
            {
                token = NextToken();
            }
            else
            {
                errorHandler.flag(token, PascalErrorCode.MISSING_COLON_EQUALS, this);
            }

            ExpressionParser expressionParser = new ExpressionParser(this);

            assignNode.AddChild(expressionParser.Parse(token));

            return(assignNode);
        }
        private ICodeNode ParseTerm(Token token)
        {
            ICodeNode rootNode = ParseFactor(token);

            token = CurrentToken();
            TokenType tokenType = token.type;


            while (MULT_OPS.Contains(tokenType))
            {
                ICodeNodeType nodeType = MULT_OPS_OPS_MAP[(PascalTokenType)tokenType];
                ICodeNode     opNode   = ICodeFactory.CreateICodeNode(nodeType);
                opNode.AddChild(rootNode);

                token = NextToken(); // consume the operator
                opNode.AddChild(ParseFactor(token));
                rootNode = opNode;

                token     = CurrentToken();
                tokenType = token.type;
            }

            return(rootNode);
        }
Ejemplo n.º 6
0
        // Parse a statement list.
        protected internal void ParseList(Token token, ICodeNode parentNode, PascalTokenType terminator, PascalErrorCode errorCode)
        {
            // Loop to parse each statement until the END token or the end of the source file.
            while (!(token is EofToken) && (token.type != terminator))
            {
                // Parse a statement.  The parent node adopts the statement node.
                ICodeNode statementNode = Parse(token);
                parentNode.AddChild(statementNode);

                token = CurrentToken();
                TokenType tokenType = token.type;

                // Look for semicolon between statements.
                if (tokenType == PascalTokenType.SEMICOLON)
                {
                    token = NextToken();
                }

                // If at the start of the next assignment statement, then missing a semicolon.
                else if (tokenType == PascalTokenType.IDENTIFIER)
                {
                    errorHandler.flag(token, PascalErrorCode.MISSING_SEMICOLON, this);
                }

                else if (tokenType != terminator)
                {
                    errorHandler.flag(token, PascalErrorCode.UNEXPECTED_TOKEN, this);
                    token = NextToken();
                }
            }

            if (token.type == terminator)
            {
                token = NextToken();
            }
            else
            {
                errorHandler.flag(token, errorCode, this);
            }
        }
Ejemplo n.º 7
0
        public void ParseList(Token token, ref ICodeNode parent, ILangTokenType terminator, ILangErrorCode error)
        {
            // As long as we are parseing neither endToken or terminating token
            // do this
            while (!(token is EndOfFileToken) && (token.TokenType.ToString() != terminator.ToString()))
            {
                ICodeNode statementNode = Parse(token);
                parent.AddChild(statementNode);

                // token have been moved; get the latest
                token = CurrentToken();

                if (token.TokenType == "semicolon")
                {
                    token = NextToken(); // move beyond the statement separator.
                }
                else if (token.TokenType == "identifier")
                {
                    ErrorHandler.Singleton.Flag(token, "missing_semicolon", this);
                }
                else if (token.TokenType != terminator)
                {
                    ErrorHandler.Singleton.Flag(token, "unexpected_token", this);
                    token = NextToken();
                }
            }

            if (token.TokenType == terminator)
            {
                token = NextToken();
            }
            else
            {
                ErrorHandler.Singleton.Flag(token, error, this);
            }
        }
        private ICodeNode ParseFactor(Token token)
        {
            TokenType tokenType = token.type;
            ICodeNode rootNode  = null;

            switch (tokenType.ToString())
            {
            case "IDENTIFIER":
            {
                // Look up the identifier in the symbol table stack.
                // Flag the identifier as undefined if it's not found.
                String           name = token.text.ToLower();
                SymbolTableEntry id   = symbolTableStack.Lookup(name);
                if (id == null)
                {
                    errorHandler.flag(token, PascalErrorCode.IDENTIFIER_UNDEFINED, this);
                    id = symbolTableStack.EnterLocal(name);
                }

                rootNode = ICodeFactory.CreateICodeNode(ICodeNodeTypeImplementation.VARIABLE);
                rootNode.SetAttribute(ICodeKeyImplementation.ID, id);
                id.AppendLineNumber(token.lineNumber);

                token = NextToken();      // consume the identifier
                break;
            }

            case "INTEGER":
            {
                // Create an INTEGER_CONSTANT node as the root node.
                rootNode = ICodeFactory.CreateICodeNode(ICodeNodeTypeImplementation.INTEGER_CONSTANT);
                rootNode.SetAttribute(ICodeKeyImplementation.VALUE, token.value);

                token = NextToken();      // consume the number
                break;
            }

            case "REAL":
            {
                // Create an REAL_CONSTANT node as the root node.
                rootNode = ICodeFactory.CreateICodeNode(ICodeNodeTypeImplementation.REAL_CONSTANT);
                rootNode.SetAttribute(ICodeKeyImplementation.VALUE, token.value);

                token = NextToken();      // consume the number
                break;
            }

            case "STRING":
            {
                String value = (String)token.value;

                // Create a STRING_CONSTANT node as the root node.
                rootNode = ICodeFactory.CreateICodeNode(ICodeNodeTypeImplementation.STRING_CONSTANT);
                rootNode.SetAttribute(ICodeKeyImplementation.VALUE, value);

                token = NextToken();      // consume the string
                break;
            }

            case "NOT":
            {
                token = NextToken();      // consume the NOT

                // Create a NOT node as the root node.
                rootNode = ICodeFactory.CreateICodeNode(ICodeNodeTypeImplementation.NOT);

                // Parse the factor.  The NOT node adopts the
                // factor node as its child.
                rootNode.AddChild(ParseFactor(token));

                break;
            }

            case "LEFT_PAREN":
            {
                token = NextToken();          // consume the (

                // Parse an expression and make its node the root node.
                rootNode = ParseExpression(token);

                // Look for the matching ) token.
                token = CurrentToken();
                if (token.type == PascalTokenType.RIGHT_PAREN)
                {
                    token = NextToken();      // consume the )
                }
                else
                {
                    errorHandler.flag(token, PascalErrorCode.MISSING_RIGHT_PAREN, this);
                }
                break;
            }

            default:
            {
                errorHandler.flag(token, PascalErrorCode.UNEXPECTED_TOKEN, this);
                break;
            }
            }

            return(rootNode);
        }