grammar python_v3;

//parser grammar python_v3;
options
{
//	output = AST;
//	k = 2;
	language = Java;
} 

tokens {
    INDENT;
    DEDENT;
}
 
@lexer::header {
	package org.eclipse.dltk.python.internal.core.parsers;
}

@parser::header {
package org.eclipse.dltk.python.internal.core.parsers;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.dltk.ast.DLTKToken;
import org.eclipse.dltk.ast.declarations.Decorator;
import org.eclipse.dltk.ast.declarations.MethodDeclaration;
import org.eclipse.dltk.ast.declarations.ModuleDeclaration;
import org.eclipse.dltk.ast.expressions.Expression;
import org.eclipse.dltk.ast.expressions.ExpressionList;
import org.eclipse.dltk.ast.expressions.NumericLiteral;
import org.eclipse.dltk.ast.expressions.StringLiteral;
import org.eclipse.dltk.ast.references.VariableReference;
import org.eclipse.dltk.ast.statements.Block;
import org.eclipse.dltk.ast.statements.Statement;
import org.eclipse.dltk.compiler.problem.IProblemReporter;
import org.eclipse.dltk.python.parser.ast.PythonArgument;
import org.eclipse.dltk.python.parser.ast.PythonAssertStatement;
import org.eclipse.dltk.python.parser.ast.PythonClassDeclaration;
import org.eclipse.dltk.python.parser.ast.PythonDelStatement;
import org.eclipse.dltk.python.parser.ast.PythonExceptStatement;
import org.eclipse.dltk.python.parser.ast.PythonForStatement;
import org.eclipse.dltk.python.parser.ast.PythonImportFromStatement;
import org.eclipse.dltk.python.parser.ast.PythonImportStatement;
import org.eclipse.dltk.python.parser.ast.PythonRaiseStatement;
import org.eclipse.dltk.python.parser.ast.PythonTryStatement;
import org.eclipse.dltk.python.parser.ast.PythonWhileStatement;
import org.eclipse.dltk.python.parser.ast.PythonYieldStatement;
import org.eclipse.dltk.python.parser.ast.expressions.Assignment;
import org.eclipse.dltk.python.parser.ast.expressions.BinaryExpression;
import org.eclipse.dltk.python.parser.ast.expressions.CallHolder;
import org.eclipse.dltk.python.parser.ast.expressions.ComplexNumericLiteral;
import org.eclipse.dltk.python.parser.ast.expressions.EmptyExpression;
import org.eclipse.dltk.python.parser.ast.expressions.ExtendedVariableReference;
import org.eclipse.dltk.python.parser.ast.expressions.IndexHolder;
import org.eclipse.dltk.python.parser.ast.expressions.NotStrictAssignment;
import org.eclipse.dltk.python.parser.ast.expressions.PrintExpression;
import org.eclipse.dltk.python.parser.ast.expressions.PythonAllImportExpression;
import org.eclipse.dltk.python.parser.ast.expressions.PythonDictExpression;
import org.eclipse.dltk.python.parser.ast.expressions.PythonForListExpression;
import org.eclipse.dltk.python.parser.ast.expressions.PythonFunctionDecorator;
import org.eclipse.dltk.python.parser.ast.expressions.PythonImportAsExpression;
import org.eclipse.dltk.python.parser.ast.expressions.PythonImportExpression;
import org.eclipse.dltk.python.parser.ast.expressions.PythonLambdaExpression;
import org.eclipse.dltk.python.parser.ast.expressions.PythonListExpression;
import org.eclipse.dltk.python.parser.ast.expressions.PythonListForExpression;
import org.eclipse.dltk.python.parser.ast.expressions.PythonSubscriptExpression;
import org.eclipse.dltk.python.parser.ast.expressions.PythonTestListExpression;
import org.eclipse.dltk.python.parser.ast.expressions.PythonTupleExpression;
import org.eclipse.dltk.python.parser.ast.expressions.UnaryExpression;
import org.eclipse.dltk.python.parser.ast.statements.BreakStatement;
import org.eclipse.dltk.python.parser.ast.statements.ContinueStatement;
import org.eclipse.dltk.python.parser.ast.statements.EmptyStatement;
import org.eclipse.dltk.python.parser.ast.statements.ExecStatement;
import org.eclipse.dltk.python.parser.ast.statements.IfStatement;
import org.eclipse.dltk.python.parser.ast.statements.ReturnStatement;
import org.eclipse.dltk.python.parser.ast.statements.TryFinallyStatement;
import org.eclipse.dltk.python.parser.ast.PythonWithStatement;
}
@lexer::members {
/** Handles context-sensitive lexing of implicit line joining such as
 *  the case where newline is ignored in cases like this:
 *  a = [3,
 *       4]
 */
public int implicitLineJoiningLevel = 0;
public int startPos=-1;
public void emitErrorMessage(String msg) {
}
}
@parser::members {
public DLTKPythonErrorReporter reporter;
	
public ModuleDeclaration decl;
	
public int length;
public DLTKTokenConverter converter;
DLTKToken toDLTK(Token token) {
	return converter.convert(token);
}
public void emitErrorMessage(String msg) {
	reporter.reportMessage(msg);
}
public void reportError(RecognitionException e) {
	if( reporter != null ) {
		reporter.reportError(e);
	}
}
public void setStartEndForEmbracedExpr(Expression exp, Token lb, Token rb)
{
	exp.setStart(toDLTK(lb).getColumn());
	exp.setEnd(toDLTK(rb).getColumn()+1);
}
}

@rulecatch {
catch (RecognitionException re) {
	if( reporter != null ) {
		reporter.reportError(re);
	}
	recover(input,re);
}
catch (Throwable extre) {
	//System.err.println(t);
	if( reporter != null ) {
		reporter.reportThrowable(extre);
	}
}
}

// Parser rules
file_input:
    	( 
    		NEWLINE
    		|    	
    		s = stmt
    			{ 
    				//statements.addAll( s );     
    				if( s != null ) {
    					Iterator i = s.iterator();
    					while( i.hasNext() ) {
    						Statement sst = (Statement)i.next();
    						if( sst != null ) {
		    					decl.addStatement( sst );
    						}
    					}
    				}
    			} 
    	
    	)*
    	EOF
	//{
	//	decl.setStatements( statements );
	//}
	;

// Decorator grammar. 2.4.x
// decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
// decorators: decorator+

decorator returns [ Decorator decorator = null ]:
	dec = DECORATOR_S
	dottedName = dot_name
	(
	 	lp0 = LPAREN
			arguments = arglist
		rp0 = RPAREN
			{
				decorator = new PythonFunctionDecorator( toDLTK( dottedName), toDLTK(dec), toDLTK(rp0), arguments );
			}
	)?

	{
		if( decorator == null ) {
			decorator = new PythonFunctionDecorator( toDLTK( dottedName ), toDLTK(dec) );
		}
	}
	NEWLINE
	;

decoraror_list returns [List decorators = new ArrayList() ]:
	(
		dec = decorator		
		{
			if( dec != null ) {
				decorators.add( dec );
			}
		}	
	)+
	;
//
// Function declaration
funcdef returns [ MethodDeclaration methodDeclaration = null; ]:
	( 
		decorators = decoraror_list 
	)?
	w = 'def' 
	tu = NAME
	{
		methodDeclaration = new MethodDeclaration( toDLTK( w ), toDLTK( tu ) );
		if( decorators != null ) {
			methodDeclaration.setDecorators( decorators );
		}
		//this.fParameters.clear();
		
		List params = new ArrayList();
		
		//Block body;
   	}
	parameters[ params ]
	{
		methodDeclaration.acceptArguments( params ); 
	}
        e = COLON
        body = suite
	{
		methodDeclaration.acceptBody( body );
	}       
;
	
// function parameters
parameters[ List params ]:
	LPAREN 
	(varargslist[ params  ])? 
	RPAREN
;

// List of arguments
varargslist[ List params ]:
	defparameter[params]
	(
		options { greedy=true;} :COMMA 
		defparameter[ params ]
	)*
        (COMMA
            	( STAR tu = NAME 
            		{ 
				params.add( new PythonArgument( toDLTK( tu ) ) ); 
			} 
            		(COMMA DOUBLESTAR t1 = NAME 
				{	
					params.add( new PythonArgument( toDLTK( t1 ) ) );
				}
            		)?
            		| DOUBLESTAR t2 = NAME
				{
            				params.add( new PythonArgument( toDLTK( t2 ) ) );
            			}
            	)?
        )?
	| STAR m = NAME 
		{ 
			params.add( new PythonArgument( toDLTK( m ) ) );
		}
	(COMMA 
		DOUBLESTAR m1 = NAME
			{
				params.add( new PythonArgument( toDLTK( m1 ) ) );
			}
	)?
	| DOUBLESTAR m2 = NAME
		{
			params.add( new PythonArgument( toDLTK( m2 ) ) );
		}
;

// Parameter with possible initialization expression.
defparameter[ List params ]:
	lastParam = fpdef[ params ]
	(ASSIGN
		initExpr=test
		{					
			if( lastParam != null ) {
				lastParam.assign( initExpr );
			}				
		}
	)?
;

// Parameter declaration
fpdef [ List params ] returns [ PythonArgument argument = null ]:
    	tu = NAME
		{
			argument = new PythonArgument( toDLTK( tu ) );
			params.add( argument );
		}	  
	|LPAREN fplist[params] RPAREN
;

//
fplist [List params ]:   
	fpdef[ params ] 
	(options { greedy=true; }:
		COMMA fpdef[ params ]
	)*
	(COMMA)?
;
////////////////////////////////////////////////////////////////////
//// Statements Part////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////

// Statement rule

simple_stmt [ List stmts ]:
	small_stmt[ stmts ]
	(options { greedy = true; }:
		SEMI small_stmt[ stmts ] 
	) * (SEMI)?
	NEWLINE
	;	stmt returns [ ArrayList statements = new ArrayList( ) ]:
	(
		{
		List simpleStatements = new ArrayList();
		}
		simple_stmt[ simpleStatements ] { statements.addAll( simpleStatements ); }
		|					
		compoundStatement = compound_stmt { statements.add( compoundStatement ); }
	)
	;

// Simple statement rule.

// Small statement declaration
small_stmt [ List stmts ] returns [ Statement rstatement = null ]: 
	(
	  statement1 = expr_stmt { rstatement = statement1; }
	| statement2 = print_stmt{ rstatement = statement2; }
	| statement3 = del_stmt{ rstatement = statement3; }
	| statement4 = pass_stmt{ rstatement = statement4; }
	| statement5 = flow_stmt{ rstatement = statement5; }
	| statement6 = import_stmt{ rstatement = statement6; }
	| statement7 = global_stmt{ rstatement = statement7; }
	| statement8 = exec_stmt{ rstatement = statement8; }
	| statement9 = assert_stmt{ rstatement = statement9; }
	)
	{
		if( rstatement != null )
			stmts.add( rstatement );
	}
	;		
// Expression rule
expr_stmt returns [ Expression exp = null ] :
	exp0 = testlist { exp = exp0; }
	(	
		type = augassign 
		right = testlist
			{
				if( type != 0 ) {
		 			NotStrictAssignment e = new NotStrictAssignment( exp, type, right );
			    		exp = e;
				}
				else {
					exp = new Assignment( exp, right );
				}
		 	}
		|
		(
			a = ASSIGN
			right = testlist
			{
				if( type != 0 ) {
		 			NotStrictAssignment e = new NotStrictAssignment( exp, type, right );
			    		exp = e;
				}
				else {
					exp = new Assignment( exp, right );
				}
			}
		)+
	)?
		{
			if( exp == null )
				exp = new EmptyExpression();
		}
	;	

augassign returns[ int type = 0 ] :
	PLUSEQUAL
		{
			type = Expression.E_PLUS_ASSIGN;
		}
	| MINUSEQUAL 
		{					
			type = Expression.E_MINUS_ASSIGN;		
		}
	| STAREQUAL
		{
			type = Expression.E_MULT_ASSIGN;
		}
	| SLASHEQUAL 
		{
			type = Expression.E_DIV_ASSIGN;
		}
	| PERCENTEQUAL
		{
			type = Expression.E_MOD_ASSIGN;
		}
	| AMPEREQUAL
		{
			type = Expression.E_BAND_ASSIGN;
		}
	| VBAREQUAL
		{
			type = Expression.E_BOR_ASSIGN;
		}
	| CIRCUMFLEXEQUAL
		{
			type = Expression.E_BXOR_ASSIGN;
		}
	| LEFTSHIFTEQUAL
		{
			type = Expression.E_SL_ASSIGN;
		}
	| RIGHTSHIFTEQUAL
		{
			type = Expression.E_SR_ASSIGN;
		}
	| DOUBLESTAREQUAL
		{
			type = Expression.E_DOUBLESTAR_ASSIGN;
		}
	| DOUBLESLASHEQUAL
		{
			type = Expression.E_DOUBLEDIV_ASSIGN;
		}	
	;	
// Print rule statement
print_stmt returns [ Statement statement = null ]:
	
        tu =  'print'
	(
		ex = testlist
        	| RIGHTSHIFT 
        	ex = testlist
	)?
	
	{
		statement = new PrintExpression( toDLTK( tu ), ex );
		if( ex != null ) {
			statement.setEnd(ex.sourceEnd());
		}
	}	
	;		
// Delete statement
del_stmt returns [ Statement statement = null ]: 
	sa = 'del' 
	tu = exprlist
	{
		statement = new PythonDelStatement( toDLTK( sa ), tu );
	}
	;

// Pass statement
pass_stmt returns [ Statement statement = null]: 
	tu = 'pass' 
	{
		statement = new EmptyStatement( toDLTK( tu ) );
	}
	;	

// Flow statement
flow_stmt returns [ Statement statement = null ]:
	  statement0 = break_stmt { statement = statement0; }
	| statement1 = continue_stmt{ statement = statement1; }
	| statement2 = return_stmt{ statement = statement2; }
	| statement3 = raise_stmt{ statement = statement3; }
	| statement4 = yield_stmt{ statement = statement4; }
	;	
// Break statement
break_stmt returns [ Statement statement = null ]: 
	ta = 'break'
		{
			statement = new BreakStatement( toDLTK( ta ), null, toDLTK(ta) );
		}
	;	
// Continue statement
continue_stmt returns [ Statement statement = null ]: 
	ta = 'continue' 
		{
			statement = new ContinueStatement( toDLTK( ta ), null, toDLTK(ta) );
		}
	;	
// Return statement
return_stmt returns [ Statement statement = null ]: 
	ra = 'return' 
		( tu = testlist )?
		{
			DLTKToken ret = toDLTK(ra);
			int end = ret.getColumn()+ret.getText().length();
			if( tu != null ) {
				end = tu.sourceEnd();
			}
			statement = new ReturnStatement( toDLTK( ra ), tu , end );
		}
	;	

// Yield statement
yield_stmt returns [ PythonYieldStatement statement = null ]: 
	tu = 'yield'
	r = testlist
	{
		statement = new PythonYieldStatement( toDLTK( tu ), r );
	}
	;	
// Exception raise statement
raise_stmt returns [ PythonRaiseStatement statement = null ]:
	tu = 'raise'
	{
		statement = new PythonRaiseStatement( toDLTK( tu ) );
		int end = -1;
	}
	(
		e1 = test 
		{
			statement.acceptExpression1( e1 );
			if( e1 != null && e1.sourceEnd() > end ) {
				end = e1.sourceEnd();
			}
		}
		( COMMA
			e2 = test 
			{
				statement.acceptExpression2( e2 );
				if( e2 != null && e2.sourceEnd() > end ) {
					end = e2.sourceEnd();
				}
			}
			( COMMA
				e3 = test
		   		{
		   			statement.acceptExpression3( e3 );
		   			if( e3 != null && e3.sourceEnd() > end ) {
						end = e3.sourceEnd();
					}
		   		}		 
		 	)?
		 )?
	)?
	;	


import_stmt returns [ Statement statement = null ] :         		
    	{
    		Expression impExpr;
    		String impName;
    		String impName2;
    		//Token moduleName;		
    		
    		PythonTestListExpression importNames = new PythonTestListExpression();    		
    	}    
    	
    	(    		
    		(	  			       
    			tu ='import'
    			{	    	
    				statement = new PythonImportStatement( toDLTK( tu ), importNames );
    				//Expression expr0 = null;
    			}
    			expr0 = module_imp
    				{
    					importNames.setStart(expr0.sourceStart());
    					importNames.setEnd(expr0.sourceEnd());
    					importNames.addExpression( expr0 );
    					if( expr0.sourceEnd() > statement.sourceEnd() ) {
    						statement.setEnd( expr0.sourceEnd() );
    					}
    				}
    			
    			( COMMA
    				expr0 = module_imp
    				{
    					importNames.addExpression( expr0 );
    					importNames.setEnd( expr0.sourceEnd());
    					if( expr0.sourceEnd() > statement.sourceEnd() ) {
    						statement.setEnd( expr0.sourceEnd() );
    					}
    				}
    			)*
		)
		|
		r = 'from'
		moduleName = dot_name
		
		'import'
		(
        		(
					{
						//moduleName.setColumn(moduleName.getColumn()-1);
        				statement = new PythonImportFromStatement( toDLTK( r ), new VariableReference( toDLTK( moduleName ) ), importNames );
        				//Expression expr0 = null;
        			}
        			expr0 = module_imp
    					{
    						importNames.setStart(expr0.sourceStart());
    						importNames.setEnd(expr0.sourceEnd());
    						importNames.addExpression( expr0 );
    						if( expr0.sourceEnd() > statement.sourceEnd() ) {
    							statement.setEnd( expr0.sourceEnd() );
    						}
    					}
    				( COMMA
    					expr0 = module_imp
    						{
    							importNames.addExpression( expr0 );
    							importNames.setEnd( expr0.sourceEnd());
    							if( expr0.sourceEnd() > statement.sourceEnd() ) {
    								statement.setEnd( expr0.sourceEnd() );
    							}
    						}
    				)*
    			)
    			|
    			( 
				STAR
				{
					//moduleName.setColumn(moduleName.getColumn()-1);
					statement = new PythonImportFromStatement( toDLTK( r ), new VariableReference( toDLTK( moduleName ) ), new PythonAllImportExpression( ) );
				} 
			)
    		)
    	)
	;		
	
dotted_name returns [ Token token = null ]:
	{		
		String value = "";
	}
	n =NAME
	{
		value += n.getText();
	}
	(
		DOT
		n2 =NAME
		{
			value += "." + n2.getText();
		}
	)+
	{
		token = new CommonToken( n );
		token.setText( value );
		//token.setColumn( n.getColumn() );
	}
	;		

dot_name returns [ Token token = null ]:
	(
		moduleName1 = dotted_name
		{
	    		token = moduleName1;
	    	}
	)
	|
	(
		moduleName2 =NAME
		{
			token = moduleName2;
		}
	)
	{
		if( token != null ) {
			//int column = token.getColumn();
			//token.setColumn( column -1 );
		}
	}
	;		
module_imp returns [ Expression expr = null ]:	
	impName = dot_name	
	{
		expr = new PythonImportExpression( toDLTK( impName ) );
	}
	( 
		'as'// this is should be as.
		as =NAME
			{
				expr = new PythonImportAsExpression( toDLTK( impName ), toDLTK( as ) );
			}
	)?
	;		

// TODO: Not Implemented at all yet.
global_stmt returns [ Statement statement = null ]:
	 'global' NAME (COMMA NAME)*
	;		
	
// TODO: Not Implemented at all yet.
exec_stmt  returns [ Statement statement = null]:
	e = 'exec' ex = expr { statement = new ExecStatement(this.converter.convert(e), ex); } 
	('in' 
		ex = test { ((ExecStatement)statement).acceptIn(ex); } 
	 (COMMA ex = test { ((ExecStatement)statement).acceptIn2(ex); }
	)?)?
	;		
// Assert statement
assert_stmt returns [ PythonAssertStatement statement = null ]:
	tu ='assert'
	exp1 = test 
	( COMMA exp2 = test )?
		{
			statement = new PythonAssertStatement( toDLTK( tu ), exp1, exp2 );
		}
	;		

// Compound statement
compound_stmt returns [ Statement statement = null ]:
	statement0 = if_stmt { statement = statement0; }
	| statement1 = while_stmt{ statement = statement1; }
	| statement2 = for_stmt{ statement = statement2; }
	| statement3 = try_stmt{ statement = statement3; }
	| statement4 = funcdef{ statement = statement4; }
	| statement5 = classdef{ statement = statement5; }
	| statement6 = with_stmt {statement = statement6; }
	;		
// If Statement
if_stmt returns [ IfStatement statement = null ]: 
		is ='if' 
		mn = test
		COLON 
		body = suite
		{ 
			IfStatement t,base;
			List ifs = new ArrayList();
			statement = new IfStatement( toDLTK( is ), mn, body ); 
			statement.setEnd(body.sourceEnd());
			ifs.add(statement);
			base = statement;
			t = statement; 
		}		
		
		(
			z ='elif'
			mn = test 
			COLON 
			body=suite
				{ 
					IfStatement elseIfStatement = new IfStatement( toDLTK( z ), mn, body );
					t.acceptElse( elseIfStatement );
					t = elseIfStatement;
					ifs.add(t);
					for(Iterator i = ifs.iterator(); i.hasNext(); ((IfStatement)i.next()).setEnd(body.sourceEnd()));
					base.setEnd(elseIfStatement.sourceEnd());
				} 
		)*
		(
			'else' 
			COLON 
			body = suite  		
				{ 
					t.setElse( body );
					for(Iterator i = ifs.iterator(); i.hasNext(); ((IfStatement)i.next()).setEnd(body.sourceEnd()));
				} 
		)?
	;		
// While statement
while_stmt returns [ PythonWhileStatement whileStatement = null ]:
		is ='while'
		expression = test
		COLON		
		body = suite
			{ 
				whileStatement = new PythonWhileStatement( toDLTK( is ), expression, body ); 
			}
		(
			'else' COLON 
			body = suite
				{ 
					whileStatement.setElseStatement( body ); 
				}
		)?
	;		
// For statement
for_stmt returns [ PythonForStatement statement = null]:
		is ='for' 
		mains = exprlist 
		'in'
		conds = testlist
		COLON 
		body = suite 
			{
				statement = new PythonForStatement( toDLTK( is ), mains, conds, body );
			}
		(
			'else' 
			COLON 
			body = suite
				{
					statement.acceptElse( body );
				}
		)?
	;	
	
// Try Statement
// not fully implemented yet
try_stmt returns [ PythonTryStatement statement = null  ]:
	is ='try' 
	COLON
		{
			Token lastTok = is;
			
        		List catches = new ArrayList();
		}
    	body = suite
    	(
        (        	
		( 
			ex_='except'
			(
				t1 = test
				(COMMA t2 = test)?
			)?
			COLON
			su = suite
			{
				lastTok = ex_;
				catches.add( new PythonExceptStatement( toDLTK( ex_ ), t1, t2, su ) );
			}
		)+
		(
			( elseT = 'else'
				COLON
				elseBlock = suite 
				{
					lastTok = elseT;
				}			
	         	)	        	
        		
        	)?
        	
        )
        |
        ( 
        	fin ='finally' 
        	{
	       		lastTok = fin;
        	}
        	COLON 
        	su = suite
	       	{
        		catches.add( new TryFinallyStatement( toDLTK( fin ), su ) );
        	}
	)
	)
        {
		statement = new PythonTryStatement( toDLTK( is ), body, catches );
		statement.setElseStatement( elseBlock );
        }
	;
// Suite rule
suite returns [ Block statement = new Block() ]:
	  {
	  	ArrayList l = new ArrayList();		
	  	int startPos = -1;
	  	int endPos = -1;
	  } 	  
	  (
	  	simple_stmt[ l ] 
	  	{
	  		Iterator i = l.iterator();
	  		while( i.hasNext()) {
	  			Statement sst = (Statement)i.next();
	  			if( sst != null ) {
	  				if( sst.sourceStart() < startPos || startPos == -1 ) {
	  					startPos = sst.sourceStart();
	  				} 
	  				if( sst.sourceEnd() > endPos || endPos == -1 ) {
	  					endPos = sst.sourceEnd();
	  				}
	  				statement.addStatement( sst );
	  			}
	  		}
	  	}
	  	| 
	  	NEWLINE
	  	ind = INDENT
	  		{
	  			if( ind != null ) {
	  				
		  			int s = converter.convert( ind ).getColumn();
		  			if( s < startPos && s != -1 ) {
		  				startPos = s;
		  			}
	  			}
	  			//ArrayList k;
	  		}
	  	(
	  		k = stmt 
	  		{
	  			//l.addAll( k );
	  			if( k != null ) {
		  			Iterator i = k.iterator();
  					while( i.hasNext() ) {
	  					Statement sst = (Statement)i.next();
	  					if( sst != null ) {
	  						statement.addStatement( sst );
	  						if( sst.sourceStart() < startPos || startPos == -1 ) {
	  							startPos = sst.sourceStart();
	  						} 
	  						if( sst.sourceEnd() > endPos || endPos == -1 ) {
	  							endPos = sst.sourceEnd();
	  						}
	  					}
	  				}
	  			}
	  		}
	  	)+  
	  	d =DEDENT
	  		{
	  			if( d != null ) {
		  			int e = converter.convert( d ).getColumn() - 1;
		  			if( e > endPos ) {
		  				endPos = e;
		  			}
	  			}
	  		}
	  )
	  
	  {
	   	//endPos -= 1;
	   	//statement = new Block( startPos, endPos, l );
	   	statement.setStart( startPos );
	   	//if( endPos == -1 ) {
	   	//	endPos = length;
	   	//}
	   	statement.setEnd( endPos );
	  }	  

	;		

///////////////////////////////////////////////
/// Expressions
//////////////////////////////////////////

or_test returns [ Expression exp = null ] :
	exp0 = and_test
	{
		exp = exp0;
	}
	(
		r = 'or' 
		v = and_test 
			{
				exp = new BinaryExpression( exp0, Expression.E_LOR, v);
			}
	)*
	;
//To be replaced with  'expression' (?) in some rules (as 2.5 grammar)
test returns [ Expression exp = null ]:
		exp0 = or_test {exp = exp0;}
	| 
		 exp0 = lambdef {exp = exp0;}
	;		

and_test returns [ Expression exp = null ]: 
	exp0 = not_test
	{
		exp = exp0;
	}
	( 
		m ='and' 
		v = not_test 
			{
				exp = new BinaryExpression( exp0, Expression.E_LAND,v);
			}
	)*
	;		

not_test returns [ Expression exp = null ]:
	(
		n ='not' 
		v = not_test 
			{
				exp = new UnaryExpression( toDLTK( n ), Expression.E_LNOT, v );
			}
		)
	| exp0 = comparison { exp = exp0;}
	;		

comparison returns [ Expression exp = null ]: 
	exp0 = expr
	{
		exp = exp0;
	}
	(
		tu = comp_op 
		v = expr
			{
				exp = new BinaryExpression( exp0, tu, v );
			}
		 )*
	;		

comp_op returns [ int t = Expression.E_EMPTY ] :
	 t1 =LESS  		{t = Expression.E_LT;}
	|t2 =GREATER 		{t = Expression.E_GT;}
	|t3 =EQUAL   		{t = Expression.E_EQUAL;}
	|t4 =GREATEREQUAL 	{t = Expression.E_GE;}
	|t5 =LESSEQUAL     	{t = Expression.E_LE;}
	|t6 =ALT_NOTEQUAL   	{t = Expression.E_NOT_EQUAL2;}
	|t7 =NOTEQUAL	    	{t = Expression.E_NOT_EQUAL;}	
	|t8 ='in'		{t = Expression.E_IN;}
	|t9 ='not' 'in'		{t = Expression.E_NOTIN;}///XXX://
	|t10 ='is'		{t = Expression.E_IS;}
	|t11 ='is' 'not'	{t = Expression.E_ISNOT;}//XXX://
	;	

expr returns [ Expression e = null]: 
	e0 = xor_expr
	{
		e = e0;
	}
	(
		tu = VBAR 
	 	v = xor_expr 
	 		{
	 			e = new BinaryExpression( e0, Expression.E_LOR,v);
	 		}
	 	)*
	;	

xor_expr returns [ Expression e = null ]: 
	e0 = and_expr
	{
		e = e0;
	}
	( 
		tu =CIRCUMFLEX 
		v = and_expr 
			{
				e = new BinaryExpression( e0, Expression.E_XOR,v);
			}
	)*
	;		

and_expr returns [ Expression e = null ]: 
	e0 = shift_expr 
	{
		e = e0;
	}
	(
		tu = AMPER 
	 	v = shift_expr 
	 		{
	 			e = new BinaryExpression( e0, Expression.E_LAND, v );
	 		}
	 )*
	;
shift_expr returns [ Expression e = null ]: 
	e0 = arith_expr 
	{
		e = e0;
	}
		{
			Token tk = null;
		}
	(
		(
			t1 = LEFTSHIFT 
				{
					tk = t1;
				}
			|
			t2 = RIGHTSHIFT
				{
					tk = t2;
				}
		) 
  	 	v = arith_expr 
  	 		{ 
  	 			if( tk == t1 ) 
  	 				e = new BinaryExpression( e0, Expression.E_LSHIFT, v );
  	 			else 
  	 				e = new BinaryExpression( e0, Expression.E_RSHIFT, v);
  	 		}
  	 )*
	;	

arith_expr returns [ Expression  e = null ]: 
	e0 = term 
	{
		e = e0;
	}
		{
			Token tk = null;
		}
	(
		(
			t1 = PLUS
				{
					tk = t1;
				}
			|
			t2 = MINUS
				{ 
					tk = t2;
				}
		) 
		v = term 
			{
	 	 		if( tk == t1 ) 
	 	 			e = new BinaryExpression( e0, Expression.E_PLUS, v );
	 	 		else 
	 	 			e = new BinaryExpression( e0, Expression.E_MINUS, v );
	 	 	}
	)*
	;	

term returns [ Expression e = null]: 
	e0 = factor 
	{
		e = e0;
	}
		{
			int type = Expression.E_EMPTY;
		}
	(
		(
	  	t1 =STAR 
	  		{
	  			type = Expression.E_MULT;
	  		}
	  	| 
	  	t2 =SLASH  
	  		{
	  			type = Expression.E_DIV;
	  		}
	  	|
	   	t3 =PERCENT  
	   		{
	   			type = Expression.E_MOD;
	   		}
	   	|
	    	t4 =DOUBLESLASH  
	    		{
	    			type = Expression.E_MOD;
	    		}
		) 
  	 v = factor 
  	 	{
  	    		e = new BinaryExpression( e0,type,v );
  	    	}
	)*
	;		

factor returns [ Expression  e = new EmptyExpression() ]: 
	  {
	  	Token tk = null;
	  }
	  (
	  	t1 = PLUS
	  		{
	  			tk = t1;
	  		}
	  	|
	  	t2 = MINUS
	  		{
	  			tk = t2;
	  		}
	  	|
	  	t3 =TILDE
	  		{
	  			tk = t3;
	  		}
	  ) 
	  e0 = factor
	  	{
	  		if( tk == t1 ) {	  			
	  			e = new UnaryExpression( toDLTK( tk ), Expression.E_PLUS, e0);
	  		}
	  		else if( tk == t2 ) {
	  			e = new UnaryExpression( toDLTK( tk ), Expression.E_MINUS, e0);
	  		}
	  		else if( tk == t3 ) {
	  			e = new UnaryExpression( toDLTK( tk ), Expression.E_MINUS, e0);
	  		}	  		
	  		else {
	  			e = new UnaryExpression( toDLTK( tk ), Expression.E_FACTOR, e0);
	  		}
	  	}
	| 
	e0 = power {
		e = e0;
	}
	;		

power returns [ Expression exp = null; ]:
	 (
		exp0 = atom
		{
			//Expression ex = exp;
			exp = exp0;
		}
		( 
			ex = trailer[ exp ] 
			{
				exp = ex;
			} 
		)*
	  	(
	  		options {greedy=true;}:DOUBLESTAR 
	  		
	  		expr0 = factor 
	  		{
	  			//TODO: add factor expression.
//	  			PythonTestListExpression testListExpr = new PythonTestListExpression();
//	  			testListExpr.addExpression( exp );
//	  			testListExpr.addExpression( expr );
//	  			exp = testListExpr;
				exp = new BinaryExpression( exp, Expression.E_POWER, expr0 );
	  		}
	  	)?
	  )
	;		
// expr this is initial expression.
trailer[ Expression expr ] returns [ Expression returnExpression = null ]:
	{
		//Expression k=null;
		// Create extended variable reference.
		if( !( expr instanceof ExtendedVariableReference ) )
			expr = new ExtendedVariableReference( expr );
		ExtendedVariableReference exVariableReference = ( ExtendedVariableReference )expr;
	}
	(
		lp0 = LPAREN 
			( k = arglist )? 
		rp0 = RPAREN
			{
				// This is Call lets' create it
				if( k == null )
					k = new EmptyExpression();
				exVariableReference.addExpression( new CallHolder( toDLTK(lp0), toDLTK(rp0), k ) );
				returnExpression = exVariableReference;
			}
		| 
		lb1 = LBRACK 
		k = subscriptlist 
		rb1 = RBRACK 
			{
				// This is subscript lets return it.
				//a = new PythonSubscriptAppender(k);
				//returnExpression = ExpressionConverter.getIndexed( expr, k );
				exVariableReference.addExpression( new IndexHolder( toDLTK(lb1), toDLTK(rb1), k ) );
				returnExpression = exVariableReference;
			}
		| 
		DOT 
		ta =NAME 
			{
				//a=new PythonFieldAppenter(ta);
				//returnExpression = ExpressionConverter.getDotted( expr, new VariableReference( toDLTK( ta ) ) );
				//ta.setColumn(ta.getColumn()-1);
				exVariableReference.addExpression( new VariableReference( toDLTK( ta ) ) );
				returnExpression = exVariableReference;
			}
	)
	;
	
atom returns [ Expression exp = null ]:
	  lb = LPAREN ( exp0 = tuplelist { exp = exp0;} ) rb = RPAREN { setStartEndForEmbracedExpr(exp,lb,rb); }
	| lb = LPAREN { exp = new PythonTupleExpression(); } rb = RPAREN { setStartEndForEmbracedExpr(exp,lb,rb); } // for initializations like a = ()
	| lb = LBRACK ( exp0 = listmaker {exp = exp0; } ) rb = RBRACK { setStartEndForEmbracedExpr(exp,lb,rb); }
	| lb =LBRACK { exp = new PythonListExpression( ); } rb = RBRACK { setStartEndForEmbracedExpr(exp,lb,rb); }  // for initializations like a = []
	| a1=LCURLY {lb =a1;} ( exp0 = dictmaker { exp = exp0; } ) rb = RCURLY { setStartEndForEmbracedExpr(exp,lb,rb); }
	| lb =LCURLY { exp = new PythonDictExpression(); } rb = RCURLY { setStartEndForEmbracedExpr(exp,lb,rb); }  // for initialization like a = {}
	| lb = BACKQUOTE exp0 = testlist { exp = exp0; } rb =  BACKQUOTE { setStartEndForEmbracedExpr(exp,lb,rb); }
	| n =NAME { exp = new VariableReference( toDLTK( n ) ); }	
	| i = INT  { exp = new NumericLiteral( toDLTK( i ) );} 
    	| li = LONGINT { exp=new NumericLiteral( toDLTK( li ) );}
    	| f = FLOAT    { exp=new NumericLiteral( toDLTK( f ) );}
    	| c = COMPLEX  { exp=new ComplexNumericLiteral( toDLTK( c ) ); }
	|
	(
		s = STRING
			{ 
				if( exp != null && exp instanceof StringLiteral  )
					exp = new StringLiteral( exp.sourceStart(), toDLTK(s),  ((StringLiteral)exp).getValue() + s.getText() ); 
				else
					exp = new StringLiteral( toDLTK( s ) ); 
			}
	)+  
	;	

listmaker returns [ PythonListExpression exp = new PythonListExpression() ]:
	firstExpr = test
	(
		(
			{
				PythonListForExpression listExpr = new PythonListForExpression( firstExpr );
			}
			list_for[ listExpr ]
			{
				exp.addExpression( listExpr );
			}
		)
		|
		(
			{
				exp.addExpression( firstExpr );
			} 
			(
				options {greedy=true;}: 
				COMMA
				expr0 = test 
				{
					exp.addExpression( expr0 );
				}
			)*
			(COMMA)?
		)
	)
	;	

// Available only in python >=2.3.x
list_for [PythonListForExpression list ]:
	(
		forToken = 'for'
		expr1 = exprlist
		'in' 
		expr2 = testlist
		{
			PythonForListExpression forListExpression = new PythonForListExpression( expr1, expr2 );
			forListExpression.setStart(toDLTK(forToken).getColumn());
			list.addExpression( forListExpression );
		}
		{
			PythonListExpression ifList = null;
		}		
		(
			expr0 = list_if
			{
				if( ifList == null )
					ifList = new PythonListExpression();
				ifList.addExpression( expr0 );
				ifList.setStart(expr0.sourceStart());
				ifList.setEnd(expr0.sourceEnd());
			}
		)*
			{
				if( ifList != null )
					forListExpression.setIfListExpression( ifList );				
			}
	)+
	;	

list_if returns[ Expression expr = null ]:
	'if'
	expr0 = test {
		expr = expr0;
	}
	;		
lambdef returns [ Expression e = null ]:
	lambda = 'lambda'
	{
		//ArrayList buf = this.fParameters;
		//this.fParameters = new ArrayList();
		List params = new ArrayList ();
		//Expression statement;
	}
	( varargslist[ params ] )?
	COLON 
	statement = test
	{		
		if( statement == null ) {
			statement = new EmptyExpression( );
		}
		e = new PythonLambdaExpression( toDLTK( lambda ), params, statement );
	}
	;

subscriptlist returns [ Expression expression = null ] :  
	expression0 = subscript 
	( 
		options {greedy=true;}:COMMA 
		k = subscript 
			{
				expression = new BinaryExpression( expression0, Expression.E_COMMA, k );
			}
	)* 
	(COMMA)?
	;			

subscript returns [ PythonSubscriptExpression expression = null ]: 
	w = DOT DOT DOT
		{
			expression = new PythonSubscriptExpression( toDLTK( w ) );
		}
		
	|
	(
		{
			expression = new PythonSubscriptExpression( );	
		}
		tu = test
			{
				expression.setTest( tu );
			} 
		(
			COLON 
			(
				tu1 = test 
					{
						expression.setCondition( tu1 );
					}
			)? 
			(
				tu = sliceop 
					{
						expression.setSlice( tu );
					} 
			)?
		)?
	)
	| 
	(
		{
			expression = new PythonSubscriptExpression( );
		}
    		COLON 
    			(
    				tu1 = test 
    					{
    						expression.setCondition( tu1 );
    					}
    			)? 
    			(
    				tu = sliceop 
    					{
    						expression.setSlice( tu );
    					}
    			)?
    
	)      
    	;	    


sliceop returns [ Expression e = null ]:
	COLON
	( e0 = test { e = e0; } )?
	;		


exprlist returns [ PythonTestListExpression p = new PythonTestListExpression( ); ] :
	e = expr 
	{
		p.addExpression( e );
		p.setStart(e.sourceStart());
		p.setEnd(e.sourceEnd());
	}
	(options {k=2;greedy=true;}:
		COMMA 
		e = expr 
			{
				p.addExpression( e );
				if( e.sourceEnd() > p.sourceEnd() ) {
					p.setEnd( e.sourceEnd() );
				}
			}
	)*
	(COMMA)?
	;		

// to be replaced by 'target' in some rules(as  in 2.5 grammar)
testlist returns [ Expression p = new EmptyExpression() ]: 
	{
		PythonTestListExpression listExpression = new PythonTestListExpression();
		int end = -1;
	}
	e0 = test
	{		
		p = e0;
		listExpression.addExpression( e0 );
		if( p != null) {
			listExpression.setStart(p.sourceStart());
			end = p.sourceEnd();
			listExpression.setEnd(end);
		}
	}
    	(options {k=2;greedy=true;}:
    		COMMA
    		e0 = test
    			{
    				if( e0 != null && e0.sourceEnd() > end ) {
    					end = e0.sourceEnd();
    				}
    				listExpression.addExpression( e0 );
    				p = listExpression;
    			}
    	)*
        (options {greedy=true;}:COMMA)?
        {
        	if( end != -1 && p != null ) {
        		p.setEnd(end);
        	}
        }
    	;
tuplelist returns [ Expression p = null ]: 
	e0 = test
	{
		p = e0;
		if( p == null ) {
			p = new EmptyExpression();
		}
		//p.addExpression( e );
	}
    	(options {greedy=true;}:
    		COMMA
    		e0 = test 
    			{
    				if( !( p instanceof PythonTupleExpression ) ) {
	    				PythonTupleExpression tuple = new PythonTupleExpression();
    					tuple.addExpression( p );
    					p = tuple;
    				}
    				PythonTupleExpression tup = (PythonTupleExpression)p;
    				tup.addExpression( e0 );
    			}
    	)*
        (options {greedy=true;}:COMMA)?
    	;        	
with_stmt returns [Statement st = null]:
	w_token = 'with' 
	exp_what = test
	(
		 'as' exp_as = testlist
	)? COLON block = suite
	{
		DLTKToken token = toDLTK(w_token);
		st = new PythonWithStatement(token, exp_what, exp_as, block, token.getColumn(), block.sourceEnd());
	}
	;
//TODO: NEED to implement
dictmaker returns [ PythonDictExpression d = new PythonDictExpression() ] :
	t1 = test
	COLON
	t2 = test
		{
			d.putExpression( t1, t2 );
		}
        (
        	options {k=2;greedy=true;}:COMMA
        	t3 = test
        	COLON
        	t4 = test
        		{
        			d.putExpression( t3, t4 );
        		}
        )* 
        (COMMA)?
    	;	    	


classdef returns [ PythonClassDeclaration classDeclaration = null ]:
	c = 'class'
	tu = NAME
		{
			classDeclaration = new PythonClassDeclaration( toDLTK( tu ), toDLTK(c) );
		}				
	( 
		r =LPAREN
			(te = testlist)?
			m = RPAREN
			{
				if (null != te)
				{
					if( te instanceof ExpressionList ) {
						classDeclaration.setParents( toDLTK( r ), (ExpressionList)te, toDLTK( m ) );
					}
					else {
						ExpressionList exprList = new ExpressionList();
						exprList.setStart(te.sourceStart());
						exprList.setEnd(te.sourceEnd());
						exprList.addExpression( te );
						classDeclaration.setParents( toDLTK( r ), exprList, toDLTK( m ) );
					}
				}
					
			}
	)?
	co = COLON
	sa = suite
		{
      			classDeclaration.setBody( toDLTK(co), sa, sa.sourceEnd() );
		}	
	;		

arglist returns [ ExpressionList expressions = new ExpressionList() ]:			
	(
		k = argument 
			{
				expressions.addExpression( k );
			} 
         	( 
         		options {greedy=true;}:COMMA 
         		k = argument 
         			{
         				expressions.addExpression( k );
         			}
         	)*
		( 
			COMMA
			( 
				STAR 
				k = test 
            				{
            					expressions.addExpression( k );
            				}  
            			(
            				COMMA 
            				DOUBLESTAR 
            				k = test 
            					{
            						expressions.addExpression( k );
            					}
            			)?
          			| 
          			DOUBLESTAR 
          			k = test 
          				{
          					expressions.addExpression( k );
          				}
			)?
		)?
		|   
		STAR 
		k = test 
			{
				expressions.addExpression( k );
			} 
		(
			COMMA 
			DOUBLESTAR 
			k = test 
				{
					expressions.addExpression( k );
				}
		)?
		|
		DOUBLESTAR 
		k = test 
			{
				expressions.addExpression( k );
			}
	)
    	;	    	

argument returns [ Expression e = null ]: 
	e0 = test
	{
		e = e0;
	}
	(
		ASSIGN 
		k = test
			{
				e = new Assignment( e, k );
			}
	)?
	;

/////////////////////////////////////////////////////////////////////
//Lexer rules
//lexer grammar python_v3;ASSIGN
//@lexer::options
//{
//	k = 3;
//	testLiterals = true;
//	charVocabulary='\u0003'..'\ufffe';
//	language = Java;
//} 

LPAREN	: '(' {implicitLineJoiningLevel++;} ;

RPAREN	: ')' {implicitLineJoiningLevel--;} ;

LBRACK	: '[' {implicitLineJoiningLevel++;} ;

RBRACK	: ']' {implicitLineJoiningLevel--;} ;

COLON 	: ':' ;

COMMA	: ',' ;

SEMI	: ';' ;

PLUS	: '+' ;

MINUS	: '-' ;

STAR	: '*' ;

SLASH	: '/' ;

VBAR	: '|' ;

AMPER	: '&' ;

LESS	: '<' ;

GREATER	: '>' ;

ASSIGN	: '=' ;

PERCENT	: '%' ;

BACKQUOTE	: '`' ;

LCURLY	: '{' {implicitLineJoiningLevel++;} ;

RCURLY	: '}' {implicitLineJoiningLevel--;} ;

CIRCUMFLEX	: '^' ;

TILDE	: '~' ;

EQUAL	: '==' ;

NOTEQUAL	: '!=' ;

ALT_NOTEQUAL: '<>' ;

LESSEQUAL	: '<=' ;

LEFTSHIFT	: '<<' ;

GREATEREQUAL	: '>=' ;

RIGHTSHIFT	: '>>' ;

PLUSEQUAL	: '+=' ;

MINUSEQUAL	: '-=' ;

DOUBLESTAR	: '**' ;

STAREQUAL	: '*=' ;

DOUBLESLASH	: '//' ;

SLASHEQUAL	: '/=' ;

VBAREQUAL	: '|=' ;

PERCENTEQUAL	: '%=' ;

AMPEREQUAL	: '&=' ;

CIRCUMFLEXEQUAL	: '^=' ;

LEFTSHIFTEQUAL	: '<<=' ;

RIGHTSHIFTEQUAL	: '>>=' ;

DOUBLESTAREQUAL	: '**=' ;

DOUBLESLASHEQUAL	: '//=' ;

DOT : '.' ;

FLOAT  	:	POINTFLOAT | EXPONENTFLOAT
//	:	'.' DIGITS (Exponent)?
//    |   DIGITS ('.' (DIGITS (Exponent)?)? | Exponent)
    ;
POINTFLOAT
	:	DIGITS? FRACTION | DIGITS '.'
	;
FRACTION 
	:	'.' DIGITS
	;
EXPONENTFLOAT 
	:	(DIGITS | POINTFLOAT) Exponent
	;
LONGINT
    :   INT ('l'|'L')
    ;

fragment
Exponent
	:	('e' | 'E') ( '+' | '-' )? DIGITS
	;

INT :   // Hex
        '0' ('x' | 'X') ( '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' )+
        ('l' | 'L')?
    |   // Octal
        '0' DIGITS*
    |   '1'..'9' DIGITS*
    ;

COMPLEX
    :   INT ('j'|'J')
    |   FLOAT ('j'|'J')
    ;

fragment
DIGITS : ( '0' .. '9' )+ ;

NAME:	( 'a' .. 'z' | 'A' .. 'Z' | '_')
        ( 'a' .. 'z' | 'A' .. 'Z' | '_' | '0' .. '9' )*
    ;

/** Match various string types.  Note that greedy=false implies '''
 *  should make us exit loop not continue.
 */
STRING
    :   ('r'|'u'|'ur')?
        (   '\'\'\'' (options {greedy=false;}:.)* '\'\'\''
        |   '"""' (options {greedy=false;}:.)* '"""'
        |   '"' (ESC|~('\\'|'\n'|'"'))* '"'
        |   '\'' (ESC|~('\\'|'\n'|'\''))* '\''
        )
	; 
fragment
ESC
	:	'\\' .
	;

/** Consume a newline and any whitespace at start of next line */
CONTINUED_LINE
	:	'\\' ('\r')? '\n' (' '|'\t')* {
		 //fModule.acceptLine(getColumn());
		 /*newline();*/ $channel=HIDDEN; }
	;

WS	:	{startPos>0}?=> (' '|'\t')+ {$channel=HIDDEN;}
	; 
/** Grab everything before a real symbol.  Then if newline, kill it
 *  as this is a blank line.  If whitespace followed by comment, kill it
 *  as it's a comment on a line by itself.
 *
 *  Ignore leading whitespace when nested in [..], (..), {..}.
 */
LEADING_WS
@init {
    int spaces = 0;
}
    :   {startPos==0}?=>
    	(   {implicitLineJoiningLevel>0}? ( ' ' | '\t' )+ {$channel=HIDDEN;}
       	|	( 	' '  { spaces++; }
        	|	'\t' { spaces += 8; spaces -= (spaces \% 8); }
       		)+
        	{
            // make a string of n spaces where n is column number - 1
            char[] indentation = new char[spaces];
            for (int i=0; i<spaces; i++) {
                indentation[i] = ' ';
            }
            String s = new String(indentation);
            Token tok = new ClassicToken(LEADING_WS,new String(indentation));
            emit(tok);
        }
        	// kill trailing newline if present and then ignore
        	( ('\r')? '\n' {if (token!=null) token.setChannel(99); else $channel=HIDDEN;})*
           // {token.setChannel(99); }
        )

/*
        |   // if comment, then only thing on a line; kill so we
            // ignore totally also wack any following newlines as
            // they cannot be terminating a statement
            '#' (~'\n')* ('\n')+ 
            {if (token!=null) token.setChannel(99); else $channel=HIDDEN;}
        )?
        */
    ;

/** Comments not on line by themselves are turned into newlines because
    sometimes they are newlines like

    b = a # end of line comment

    or

    a = [1, # weird
         2]

    This rule is invoked directly by nextToken when the comment is in
    first column or when comment is on end of nonwhitespace line.

    The problem is that then we have lots of newlines heading to
    the parser.  To fix that, column==1 implies we should kill whole line.

    Consume any newlines following this comment as they are not statement
    terminators.  Don't let NEWLINE token handle them.
 */

COMMENT
@init {
    $channel=HIDDEN;
}
    :	{startPos==0}?=> (' '|'\t')* '#' (~'\n')* '\n'+
    |	{startPos>0}?=> '#' (~'\n')* // let NEWLINE handle \n unless char pos==0 for '#'
    ;
    
//SPECIAL
//{
//    int startCol = getColumn();
//}
//    :  (~'\n')* // let NEWLINE handle \n unless column = 1 for '#'
//        { $setType(Token.SKIP);        	
//        	fModule.acceptModifier($getText); 
//        	}
//        ( {startCol==1}? ('\n' {
//        	fModule.acceptLine(getColumn());newline();
//}
//        )+ )?
//    ;    
DECORATOR_S:
	'@'
;
/** Treat a sequence of blank lines as a single blank line.  If
 *  nested within a (..), {..}, or [..], then ignore newlines.
 *  If the first newline starts in column one, they are to be ignored.
 */
NEWLINE
    :   (('\r')? '\n' )+
        {if ( startPos==0 || implicitLineJoiningLevel>0 )
            $channel=HIDDEN;
        }
    ;
