Пример #1
0
        protected virtual ParenthesizedExpressionNode ParseParenthesizedExpression(IPrimaryParentNode parent, SpecialCharacterToken leftParenthesis)
        {
            // PARSE: '(' <expression> ')'
            ParenthesizedExpressionNode result = new ParenthesizedExpressionNode(parent, leftParenthesis);

            Token          token      = this.GetNextTokenxx(Preference.NegativeSign);
            ExpressionNode expression = this.ParseExpression(result, token);

            if (expression == null)
            {
                this.ReportParserError(result, SemanticErrors.MissingExpression, token);
                return(result);
            }

            // Ensure the parentheses are properly closed.
            token = this.GetNextTokenxx(Preference.Default);
            SpecialCharacterToken rightParenthesis = null;

            if (Parser.IsClosingParenthesis(token))
            {
                rightParenthesis = (SpecialCharacterToken)token;
            }
            else
            {
                this.ReportParserError(result, SemanticErrors.MissingExpressionClosingParenthesis, token);
                this.ResidueToken = token;
            }

            result.SetContents(expression, rightParenthesis);
            return(result);
        }
Пример #2
0
        /// <summary>
        /// Create a new variable reference node.
        /// </summary>
        /// <param name="parent">The parent node that defines this node.</param>
        /// <param name="token">Identifier token containing the name of the variable.</param>
        protected internal VariableReferenceleNode(IPrimaryParentNode parent, IdentifierToken token)
        {
#if DEBUG
            if (parent == null)
            {
                throw new ArgumentNullException("parent");
            }
            if (token == null)
            {
                throw new ArgumentNullException("token");
            }
#endif
            this.Parent = parent;
            this.Token  = token;
        }
Пример #3
0
        /// <summary>
        /// Create and initialize a block node.
        /// </summary>
        /// <param name="parent">The parent node to the block node.</param>
        /// <param name="token">Token for the left / opening square bracket of the block.</param>
        protected internal BlockNode(IPrimaryParentNode parent, SpecialCharacterToken token)
        {
#if DEBUG
            if (parent == null)
            {
                throw new ArgumentNullException("parent");
            }
            if (token == null)
            {
                throw new ArgumentNullException("token");
            }
#endif
            this.Arguments   = new List <BlockArgumentNode>();
            this.Parent      = parent;
            this.LeftBracket = token;
        }
Пример #4
0
        /// <summary>
        /// Create a new parenthesized expression node.
        /// </summary>
        /// <param name="parent">Parent node that defines this expression.</param>
        /// <param name="token">Left opening parenthesis of the parenthesized expression.</param>
        protected internal ParenthesizedExpressionNode(IPrimaryParentNode parent, SpecialCharacterToken token)
        {
#if DEBUG
            if (parent == null)
            {
                throw new ArgumentNullException("parent");
            }
            if (!Parser.IsOpeningParenthesis(token))
            {
                // We do expect the caller to this method to have ensured that we are actually parsing a parenthesis.
                throw new InvalidParserOperationException("Expected opening parenthesis token ... '('");
            }
#endif
            this.Parent          = parent;
            this.LeftParenthesis = token;
        }
Пример #5
0
 protected virtual IPrimaryNode ParsePrimary(IPrimaryParentNode parent, Token token)
 {
     // PARSE: <primary> ::= identifier | <literal> | <block constructor> | ( '(' <expression> ')' )
     if (token is IdentifierToken)
     {
         return(new VariableReferenceleNode(parent, (IdentifierToken)token));
     }
     else if (Parser.IsBlockStartDelimiter(token))
     {
         return(this.ParseBlock(parent, (SpecialCharacterToken)token));
     }
     else if (Parser.IsOpeningParenthesis(token))
     {
         return(this.ParseParenthesizedExpression(parent, (SpecialCharacterToken)token));
     }
     else
     {
         return(this.ParseLiteral(parent, token));
     }
 }
Пример #6
0
 /// <summary>
 /// Create a new variable reference node.
 /// </summary>
 /// <param name="parent">The parent node that defines this node.</param>
 /// <param name="token">Identifier token containing the name of the variable.</param>
 protected internal VariableReferenceleNode(IPrimaryParentNode parent, IdentifierToken token)
 {
     #if DEBUG
     if (parent == null)
         throw new ArgumentNullException("parent");
     if (token == null)
         throw new ArgumentNullException("token");
     #endif
     this.Parent = parent;
     this.Token = token;
 }
Пример #7
0
 /// <summary>
 /// Create a new parenthesized expression node.
 /// </summary>
 /// <param name="parent">Parent node that defines this expression.</param>
 /// <param name="token">Left opening parenthesis of the parenthesized expression.</param>
 protected internal ParenthesizedExpressionNode(IPrimaryParentNode parent, SpecialCharacterToken token)
 {
     #if DEBUG
     if (parent == null)
         throw new ArgumentNullException("parent");
     if (!Parser.IsOpeningParenthesis(token))
         // We do expect the caller to this method to have ensured that we are actually parsing a parethesis.
         throw new InvalidParserOperationException("Expected opening parenthesis token ... '('");
     #endif
     this.Parent = parent;
     this.LeftParenthesis = (SpecialCharacterToken)token;
 }
Пример #8
0
        protected virtual BlockNode ParseBlock(IPrimaryParentNode parent, SpecialCharacterToken leftBracket)
        {
            // PARSE: <block constructor> ::= '[' <block body> ']'
            //      <block body> ::= [<block argument>* '|'] [<temporaries>] [<statements>]
            //      <block argument> ::= ':' identifier
            BlockNode result = new BlockNode(parent, leftBracket);

            // PARSE: [<block argument>* '|']
            // ISSUE: It this a bug in X3J20. Shouldn't it be: [<block argument>+ '|']
            // The current definition allows blocks like: [ | ] ... or ... [ | self doStuff ]  ... or ... [ | | temp | temp := self something ]
            // We assume X3J20 bug and expect: [<block argument>+ '|']
            VerticalBarToken         argumentsBar = null;
            List <BlockArgumentNode> arguments    = new List <BlockArgumentNode>();

            Token token = this.GetNextTokenxx(Preference.VerticalBar | Preference.NegativeSign);

            // Check if the block has arguments
            if (Parser.IsBlockArgumentPrefix(token))
            {
                // ... yes arguments ... parse them ...
                while (true)
                {
                    if (Parser.IsBlockArgumentPrefix(token))
                    {
                        // <block argument>
                        arguments.Add(this.ParseBlockArgument(result, (SpecialCharacterToken)token));
                    }
                    else if (token is VerticalBarToken)
                    {
                        // The '|' after the arguments.
                        argumentsBar = (VerticalBarToken)token;
                        token        = this.GetNextTokenxx(Preference.NegativeSign | Preference.VerticalBar);
                        break; // Done with block arguments
                    }
                    else
                    {
                        this.ReportParserError(result, SemanticErrors.MissingBlockClosingArgsBar, token);
                        break;
                    }
                    // Get the next token
                    token = this.GetNextTokenxx(Preference.VerticalBar | Preference.NegativeSign);
                }
            }

            // PARSE: [<temporaries>]
            ParseTemporariesResult ptr = this.ParseTemporaries(result, token);

            // PARSE: <statements>
            token = this.GetNextTokenxx(Preference.NegativeSign);
            StatementNode statements = this.ParseStatement(result, token);

            // Ensure the block is properly closed.
            SpecialCharacterToken rightBracket = null;

            token = this.GetNextTokenxx(Preference.Default);
            if (!Parser.IsBlockEndDelimiter(token))
            {
                this.ReportParserError(result, SemanticErrors.MissingBlockClosingBracket, token);
                this.ResidueToken = token;
            }
            else
            {
                rightBracket = (SpecialCharacterToken)token;
            }

            result.SetContents(arguments, argumentsBar, ptr.LeftBar, ptr.Temporaries, ptr.RightBar, statements, rightBracket);
            return(result);
        }
Пример #9
0
 /// <summary>
 /// Create and intialize a block node.
 /// </summary>
 /// <param name="parent">The parent node to the block node.</param>
 /// <param name="token">Token for the left / opening square bracket of the block.</param>
 protected internal BlockNode(IPrimaryParentNode parent, SpecialCharacterToken token)
 {
     #if DEBUG
     if (parent == null)
         throw new ArgumentNullException("parent");
     if (token == null)
         throw new ArgumentNullException("token");
     #endif
     this.Arguments = new List<BlockArgumentNode>();
     this.Parent = parent;
     this.LeftBracket = token;
 }
Пример #10
0
 protected virtual IPrimaryNode ParsePrimary(IPrimaryParentNode parent, Token token)
 {
     // PARSE: <primary> ::= identifier | <literal> | <block constructor> | ( '(' <expression> ')' )
     if (token is IdentifierToken)
         return new VariableReferenceleNode(parent, (IdentifierToken)token);
     else if (Parser.IsBlockStartDelimiter(token))
         return this.ParseBlock(parent, (SpecialCharacterToken)token);
     else if (Parser.IsOpeningParenthesis(token))
         return this.ParseParenthesizedExpression(parent, (SpecialCharacterToken)token);
     else
         return this.ParseLiteral(parent, token);
 }
Пример #11
0
        protected virtual ParenthesizedExpressionNode ParseParenthesizedExpression(IPrimaryParentNode parent, SpecialCharacterToken leftParenthesis)
        {
            // PARSE: '(' <expression> ')'
            ParenthesizedExpressionNode result = new ParenthesizedExpressionNode(parent, leftParenthesis);

            Token token = this.GetNextTokenxx(Preference.NegativeSign);
            ExpressionNode expression = this.ParseExpression(result, token);

            if (expression == null)
            {
                this.ReportParserError(result, SemanticErrors.MissingExpression, token);
                return result;
            }

            // Ensure the parenthese are properly closed.
            token = this.GetNextTokenxx(Preference.Default);
            SpecialCharacterToken rightParenthesis = null;
            if (Parser.IsClosingParenthesis(token))
            {
                rightParenthesis = (SpecialCharacterToken)token;
            }
            else
            {
                this.ReportParserError(result, SemanticErrors.MissingExpressionClosingParenthesis, token);
                this.ResidueToken = token;
            }

            result.SetContents(expression, rightParenthesis);
            return result;
        }
Пример #12
0
        protected virtual BlockNode ParseBlock(IPrimaryParentNode parent, SpecialCharacterToken leftBracket)
        {
            // PARSE: <block constructor> ::= '[' <block body> ']'
            //      <block body> ::= [<block argument>* '|'] [<temporaries>] [<statements>]
            //      <block argument> ::= ':' identifier
            BlockNode result = new BlockNode(parent, leftBracket);

            // PARSE: [<block argument>* '|']
            // ISSUE: It this a bug in X3J20. Shouldn't it be: [<block argument>+ '|']
            // The current definition allows blocks like: [ | ] ... or ... [ | self doStuff ]  ... or ... [ | | temp | temp := self something ]
            // We assume X3J20 bug and expect: [<block argument>+ '|']
            VerticalBarToken argumentsBar = null;
            List<BlockArgumentNode> arguments = new List<BlockArgumentNode>();

            Token token = this.GetNextTokenxx(Preference.VerticalBar | Preference.NegativeSign);
            // Check if the block has arguments
            if (Parser.IsBlockArgumentPrefix(token))
            {
                // ... yes arguments ... parse them ...
                while (true)
                {

                    if (Parser.IsBlockArgumentPrefix(token))
                    {
                        // <block argument>
                        arguments.Add(this.ParseBlockArgument(result, (SpecialCharacterToken)token));
                    }
                    else if (token is VerticalBarToken)
                    {
                        // The '|' after the arguments.
                        argumentsBar = (VerticalBarToken)token;
                        token = this.GetNextTokenxx(Preference.NegativeSign | Preference.VerticalBar);
                        break; // Done with block arguments
                    }
                    else
                    {
                        this.ReportParserError(result, SemanticErrors.MissingBlockClosingArgsBar, token);
                        break;
                    }
                    // Get the next token
                    token = this.GetNextTokenxx(Preference.VerticalBar | Preference.NegativeSign);
                }
            }

            // PARSE: [<temporaries>]
            ParseTemporariesResult ptr = this.ParseTemporaries(result, token);

            // PARSE: <statements>
            token = this.GetNextTokenxx(Preference.NegativeSign);
            StatementNode statements = this.ParseStatement(result, token);

            // Ensure the block is properly closed.
            SpecialCharacterToken rightBracket = null;
            token = this.GetNextTokenxx(Preference.Default) ;
            if (!Parser.IsBlockEndDelimiter(token))
            {
                this.ReportParserError(result, SemanticErrors.MissingBlockClosingBracket, token);
                this.ResidueToken = token;
            }
            else
            {
                rightBracket = (SpecialCharacterToken)token;
            }

            result.SetContents(arguments, argumentsBar, ptr.LeftBar, ptr.Temporaries, ptr.RightBar, statements, rightBracket);
            return result;
        }