private ParserImpl parseExpressionList(final IScope blockScope,final boolean variableDefinitionsAllowed,final boolean failOnMismatchedClosingParens) throws IOException
    {
        return new ParserImpl() {

            @Override
            public String toString()
            {
                return "parseExpressionList";
            }

            @Override
            protected ASTNode doParse() throws Exception
            {
                final Block result = new Block();
                result.setScope(blockScope);

                Token previousComma = null;
                while ( ! lexer.peek( TokenType.SEMICOLON ) ) 
                {
                    Token tok = lexer.peek();

                    // variable definition
                    boolean gotSomething = false;
                    if ( tok.hasType( TokenType.IDENTIFIER ) && 
                            blockScope.isDataTypeDefined( new Identifier( tok.getValue() ) ) ) 
                    {
                        if ( ! variableDefinitionsAllowed ) {
                            break;
                        }
                        if ( ! parseVariableDefinition( blockScope ).parse() ) {
                            return null;
                        }
                        result.addChild( lastResult );
                        gotSomething = true;
                    } 
                    else if ( parseExpression( blockScope , failOnMismatchedClosingParens ).parse() ) 
                    {
                        result.addChild( lastResult );
                        gotSomething = true;
                    } 

                    if ( ! gotSomething && previousComma != null ) {
                        throw new ParseException("Expression expected after comma" , previousComma );
                    }

                    if ( lexer.peek(TokenType.COMMA ) ) 
                    {
                        previousComma = lexer.read();
                        result.merge( previousComma );
                        continue;
                    }
                    break;
                }
                return result;
            }
        };
    }