Exemple #1
0
        protected virtual ParseTemporariesResult ParseTemporaries(FunctionNode function, Token token)
        {
            // PARSE: <temporaries> ::= '|' <temporary variable list> '|'
            ParseTemporariesResult result = new ParseTemporariesResult();

            if (!(token is VerticalBarToken))
            {
                this.ResidueToken = token;
                return(result);
            }

            result.LeftBar = (VerticalBarToken)token;
            while (true)
            {
                token = this.GetNextTokenxx(Preference.VerticalBar);
                if (token is VerticalBarToken)
                {
                    // Done with temp variables.
                    result.RightBar = (VerticalBarToken)token;
                    return(result);
                }
                if (token is IdentifierToken)
                {
                    result.Temporaries.Add(new TemporaryVariableNode(function, (IdentifierToken)token));
                }
                else
                {
                    this.ReportParserError(function, SemanticErrors.MissingClosingTempBar, token);
                    this.ResidueToken = token;
                    return(result);
                }
            }
        }
Exemple #2
0
        protected virtual MethodNode ParseMethod()
        {
            // PARSE X3J20: <method definition> ::= <message pattern> [<temporaries> ] [<statements>]
            // NB: We've extended the method definition to allow API calls into the .Net Framework,
            // PARSE: <method definition> ::= <message pattern> [<temporaries>] [<api call>] [<statements>]
            MethodNode result = this.ParseMessagePattern();
            Token      token  = this.GetNextTokenxx(Preference.NegativeSign | Preference.VerticalBar);

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

            // PARSE [<api call>]
            token = this.GetNextTokenxx(Preference.NegativeSign);
            if (Parser.IsApiOpeningDelimiter(token))
            {
                result.SetContents(this.ParseApiCall(result, (BinarySelectorToken)token));
                token = this.GetNextTokenxx(Preference.NegativeSign);
            }

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

            // Should be done.
            token = this.GetNextTokenxx(Preference.Default);
            if (!(token is EofToken))
            {
                this.ReportParserError(result, SemanticErrors.UnexpectedCodeAfterMethodDefinition, token);
            }

            result.SetContents(ptr.LeftBar, ptr.Temporaries, ptr.RightBar, statements);
            return(result);
        }
Exemple #3
0
        protected virtual InitializerNode ParseInitializer()
        {
            // PARSE: <initializer definition> ::= [<temporaries>] [<statements>]
            InitializerNode result = new InitializerNode();
            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);

            // Should be done.
            token = this.GetNextTokenxx(Preference.Default);
            if (!(token is EofToken))
            {
                this.ReportParserError(result, SemanticErrors.UnexpectedCodeAfterInitializer, token);
            }

            result.SetContents(ptr.LeftBar, ptr.Temporaries, ptr.RightBar, statements);
            return(result);
        }
Exemple #4
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);
        }
Exemple #5
0
        protected virtual ParseTemporariesResult ParseTemporaries(FunctionNode function, Token token)
        {
            // PARSE: <temporaries> ::= '|' <temporary variable list> '|'
            ParseTemporariesResult result = new ParseTemporariesResult();
            if (!(token is VerticalBarToken))
            {
                this.ResidueToken = token;
                return result;
            }

            result.LeftBar = (VerticalBarToken)token;
            while (true)
            {
                token = this.GetNextTokenxx(Preference.VerticalBar);
                if (token is VerticalBarToken)
                {
                    // Done with temp variables.
                    result.RightBar = (VerticalBarToken)token;
                    return result;
                }
                if (token is IdentifierToken)
                {
                    result.Temporaries.Add(new TemporaryVariableNode(function, (IdentifierToken)token));
                }
                else
                {
                    this.ReportParserError(function, SemanticErrors.MissingClosingTempBar, token);
                    this.ResidueToken = token;
                    return result;
                }
            }
        }