/*
 [The "BSD license"]
 Copyright (c) 2010 Terence Parr
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
 3. The name of the author may not be used to endorse or promote products
    derived from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
lexer grammar ActionTranslator;
options {
  filter=true;  // try all non-fragment rules in order specified
  // output=template;  TODO: can we make tokens return templates somehow?
}

@header {
package org.antlr.grammar.v3;
import org.stringtemplate.v4.ST;
import org.antlr.runtime.*;
import org.antlr.tool.*;
import org.antlr.codegen.*;

import org.antlr.runtime.*;
import java.util.List;
import java.util.ArrayList;
import org.antlr.grammar.v3.ANTLRParser;

}

@members {
public List chunks = new ArrayList();
Rule enclosingRule;
int outerAltNum;
Grammar grammar;
CodeGenerator generator;
Token actionToken;

	public ActionTranslator(CodeGenerator generator,
								 String ruleName,
								 GrammarAST actionAST)
	{
		this(new ANTLRStringStream(actionAST.token.getText()));
		this.generator = generator;
		this.grammar = generator.grammar;
	    this.enclosingRule = grammar.getLocallyDefinedRule(ruleName);
	    this.actionToken = actionAST.token;
	    this.outerAltNum = actionAST.outerAltNum;
	}

	public ActionTranslator(CodeGenerator generator,
								 String ruleName,
								 Token actionToken,
								 int outerAltNum)
	{
		this(new ANTLRStringStream(actionToken.getText()));
		this.generator = generator;
		grammar = generator.grammar;
	    this.enclosingRule = grammar.getRule(ruleName);
	    this.actionToken = actionToken;
		this.outerAltNum = outerAltNum;
	}

/** Return a list of strings and ST objects that
 *  represent the translated action.
 */
public List translateToChunks() {
	// System.out.println("###\naction="+action);
	Token t;
	do {
		t = nextToken();
	} while ( t.getType()!= Token.EOF );
	return chunks;
}

public String translate() {
	List theChunks = translateToChunks();
	//System.out.println("chunks="+a.chunks);
	StringBuffer buf = new StringBuffer();
	for (int i = 0; i < theChunks.size(); i++) {
		Object o = (Object) theChunks.get(i);
		if ( o instanceof ST ) buf.append(((ST)o).render());
		else buf.append(o);
	}
	//System.out.println("translated: "+buf.toString());
	return buf.toString();
}

public List translateAction(String action) {
	String rname = null;
	if ( enclosingRule!=null ) {
		rname = enclosingRule.name;
	}
	ActionTranslator translator =
		new ActionTranslator(generator,
								  rname,
								  new CommonToken(ANTLRParser.ACTION,action),outerAltNum);
    return translator.translateToChunks();
}

public boolean isTokenRefInAlt(String id) {
    return enclosingRule.getTokenRefsInAlt(id, outerAltNum)!=null;
}
public boolean isRuleRefInAlt(String id) {
    return enclosingRule.getRuleRefsInAlt(id, outerAltNum)!=null;
}
public Grammar.LabelElementPair getElementLabel(String id) {
    return enclosingRule.getLabel(id);
}

public void checkElementRefUniqueness(String ref, boolean isToken) {
		List refs = null;
		if ( isToken ) {
		    refs = enclosingRule.getTokenRefsInAlt(ref, outerAltNum);
		}
		else {
		    refs = enclosingRule.getRuleRefsInAlt(ref, outerAltNum);
		}
		if ( refs!=null && refs.size()>1 ) {
			ErrorManager.grammarError(ErrorManager.MSG_NONUNIQUE_REF,
									  grammar,
									  actionToken,
									  ref);
		}
}

/** For \$rulelabel.name, return the Attribute found for name.  It
 *  will be a predefined property or a return value.
 */
public Attribute getRuleLabelAttribute(String ruleName, String attrName) {
	Rule r = grammar.getRule(ruleName);
	AttributeScope scope = r.getLocalAttributeScope(attrName);
	if ( scope!=null && !scope.isParameterScope ) {
		return scope.getAttribute(attrName);
	}
	return null;
}

AttributeScope resolveDynamicScope(String scopeName) {
	if ( grammar.getGlobalScope(scopeName)!=null ) {
		return grammar.getGlobalScope(scopeName);
	}
	Rule scopeRule = grammar.getRule(scopeName);
	if ( scopeRule!=null ) {
		return scopeRule.ruleScope;
	}
	return null; // not a valid dynamic scope
}

protected ST template(String name) {
	ST st = generator.getTemplates().getInstanceOf(name);
	chunks.add(st);
	return st;
}


}

/**	$x.y	x is enclosing rule, y is a return value, parameter, or
 * 			predefined property.
 *
 * 			r[int i] returns [int j]
 * 				:	{$r.i, $r.j, $r.start, $r.stop, $r.st, $r.tree}
 * 				;
 */
SET_ENCLOSING_RULE_SCOPE_ATTR
	:	'$' x=ID '.' y=ID WS? '=' expr=ATTR_VALUE_EXPR ';'
							{enclosingRule!=null &&
	                         $x.text.equals(enclosingRule.name) &&
	                         enclosingRule.getLocalAttributeScope($y.text)!=null}?
		//{System.out.println("found \$rule.attr");}
		{
		ST st = null;
		AttributeScope scope = enclosingRule.getLocalAttributeScope($y.text);
		if ( scope.isPredefinedRuleScope ) {
			if ( $y.text.equals("st") || $y.text.equals("tree") ) {
				st = template("ruleSetPropertyRef_"+$y.text);
				grammar.referenceRuleLabelPredefinedAttribute($x.text);
				st.add("scope", $x.text);
				st.add("attr", $y.text);
				st.add("expr", translateAction($expr.text));
			} else {
				ErrorManager.grammarError(ErrorManager.MSG_WRITE_TO_READONLY_ATTR,
										  grammar,
										  actionToken,
										  $x.text,
										  $y.text);
			}
		}
	    else if ( scope.isPredefinedLexerRuleScope ) {
	    	// this is a better message to emit than the previous one...
			ErrorManager.grammarError(ErrorManager.MSG_WRITE_TO_READONLY_ATTR,
									  grammar,
									  actionToken,
									  $x.text,
									  $y.text);
	    }
		else if ( scope.isParameterScope ) {
			st = template("parameterSetAttributeRef");
			st.add("attr", scope.getAttribute($y.text));
			st.add("expr", translateAction($expr.text));
		}
		else { // must be return value
			st = template("returnSetAttributeRef");
			st.add("ruleDescriptor", enclosingRule);
			st.add("attr", scope.getAttribute($y.text));
			st.add("expr", translateAction($expr.text));
		}
		}
	;
ENCLOSING_RULE_SCOPE_ATTR
	:	'$' x=ID '.' y=ID	{enclosingRule!=null &&
	                         $x.text.equals(enclosingRule.name) &&
	                         enclosingRule.getLocalAttributeScope($y.text)!=null}?
		//{System.out.println("found \$rule.attr");}
		{
		if ( isRuleRefInAlt($x.text)  ) {
			ErrorManager.grammarError(ErrorManager.MSG_RULE_REF_AMBIG_WITH_RULE_IN_ALT,
									  grammar,
									  actionToken,
									  $x.text);
		}
		ST st = null;
		AttributeScope scope = enclosingRule.getLocalAttributeScope($y.text);
		if ( scope.isPredefinedRuleScope ) {
			st = template("rulePropertyRef_"+$y.text);
			grammar.referenceRuleLabelPredefinedAttribute($x.text);
			st.add("scope", $x.text);
			st.add("attr", $y.text);
		}
	    else if ( scope.isPredefinedLexerRuleScope ) {
	    	// perhaps not the most precise error message to use, but...
			ErrorManager.grammarError(ErrorManager.MSG_RULE_HAS_NO_ARGS,
									  grammar,
									  actionToken,
									  $x.text);
	    }
		else if ( scope.isParameterScope ) {
			st = template("parameterAttributeRef");
			st.add("attr", scope.getAttribute($y.text));
		}
		else { // must be return value
			st = template("returnAttributeRef");
			st.add("ruleDescriptor", enclosingRule);
			st.add("attr", scope.getAttribute($y.text));
		}
		}
	;

/** Setting $tokenlabel.attr or $tokenref.attr where attr is predefined property of a token is an error. */
SET_TOKEN_SCOPE_ATTR
	:	'$' x=ID '.' y=ID WS? '='
							 {enclosingRule!=null && input.LA(1)!='=' &&
	                         (enclosingRule.getTokenLabel($x.text)!=null||
	                          isTokenRefInAlt($x.text)) &&
	                         AttributeScope.tokenScope.getAttribute($y.text)!=null}?
		//{System.out.println("found \$tokenlabel.attr or \$tokenref.attr");}
		{
		ErrorManager.grammarError(ErrorManager.MSG_WRITE_TO_READONLY_ATTR,
								  grammar,
								  actionToken,
								  $x.text,
								  $y.text);
		}
	;

/** $tokenlabel.attr or $tokenref.attr where attr is predefined property of a token.
 *  If in lexer grammar, only translate for strings and tokens (rule refs)
 */
TOKEN_SCOPE_ATTR
	:	'$' x=ID '.' y=ID	{enclosingRule!=null &&
	                         (enclosingRule.getTokenLabel($x.text)!=null||
	                          isTokenRefInAlt($x.text)) &&
	                         AttributeScope.tokenScope.getAttribute($y.text)!=null &&
	                         (grammar.type!=Grammar.LEXER ||
	                         getElementLabel($x.text).elementRef.token.getType()==ANTLRParser.TOKEN_REF ||
	                         getElementLabel($x.text).elementRef.token.getType()==ANTLRParser.STRING_LITERAL)}?
		// {System.out.println("found \$tokenlabel.attr or \$tokenref.attr");}
		{
		String label = $x.text;
		if ( enclosingRule.getTokenLabel($x.text)==null ) {
			// \$tokenref.attr  gotta get old label or compute new one
			checkElementRefUniqueness($x.text, true);
			label = enclosingRule.getElementLabel($x.text, outerAltNum, generator);
			if ( label==null ) {
				ErrorManager.grammarError(ErrorManager.MSG_FORWARD_ELEMENT_REF,
										  grammar,
										  actionToken,
										  "\$"+$x.text+"."+$y.text);
				label = $x.text;
			}
		}
		ST st = template("tokenLabelPropertyRef_"+$y.text);
		st.add("scope", label);
		st.add("attr", AttributeScope.tokenScope.getAttribute($y.text));
		}
	;

/** Setting $rulelabel.attr or $ruleref.attr where attr is a predefined property is an error
 *  This must also fail, if we try to access a local attribute's field, like $tree.scope = localObject
 *  That must be handled by LOCAL_ATTR below. ANTLR only concerns itself with the top-level scope
 *  attributes declared in scope {} or parameters, return values and the like.
 */
SET_RULE_SCOPE_ATTR
@init {
Grammar.LabelElementPair pair=null;
String refdRuleName=null;
}
	:	'$' x=ID '.' y=ID WS? '=' {enclosingRule!=null && input.LA(1)!='='}?
		{
		pair = enclosingRule.getRuleLabel($x.text);
		refdRuleName = $x.text;
		if ( pair!=null ) {
			refdRuleName = pair.referencedRuleName;
		}
		}
		// supercomplicated because I can't exec the above action.
		// This asserts that if it's a label or a ref to a rule proceed but only if the attribute
		// is valid for that rule's scope
		{(enclosingRule.getRuleLabel($x.text)!=null || isRuleRefInAlt($x.text)) &&
	      getRuleLabelAttribute(enclosingRule.getRuleLabel($x.text)!=null?enclosingRule.getRuleLabel($x.text).referencedRuleName:$x.text,$y.text)!=null}?
		//{System.out.println("found set \$rulelabel.attr or \$ruleref.attr: "+$x.text+"."+$y.text);}
		{
		ErrorManager.grammarError(ErrorManager.MSG_WRITE_TO_READONLY_ATTR,
								  grammar,
								  actionToken,
								  $x.text,
								  $y.text);
		}
	;

/** $rulelabel.attr or $ruleref.attr where attr is a predefined property*/
RULE_SCOPE_ATTR
@init {
Grammar.LabelElementPair pair=null;
String refdRuleName=null;
}
	:	'$' x=ID '.' y=ID {enclosingRule!=null}?
		{
		pair = enclosingRule.getRuleLabel($x.text);
		refdRuleName = $x.text;
		if ( pair!=null ) {
			refdRuleName = pair.referencedRuleName;
		}
		}
		// supercomplicated because I can't exec the above action.
		// This asserts that if it's a label or a ref to a rule proceed but only if the attribute
		// is valid for that rule's scope
		{(enclosingRule.getRuleLabel($x.text)!=null || isRuleRefInAlt($x.text)) &&
	      getRuleLabelAttribute(enclosingRule.getRuleLabel($x.text)!=null?enclosingRule.getRuleLabel($x.text).referencedRuleName:$x.text,$y.text)!=null}?
		//{System.out.println("found \$rulelabel.attr or \$ruleref.attr: "+$x.text+"."+$y.text);}
		{
		String label = $x.text;
		if ( pair==null ) {
			// \$ruleref.attr  gotta get old label or compute new one
			checkElementRefUniqueness($x.text, false);
			label = enclosingRule.getElementLabel($x.text, outerAltNum, generator);
			if ( label==null ) {
				ErrorManager.grammarError(ErrorManager.MSG_FORWARD_ELEMENT_REF,
										  grammar,
										  actionToken,
										  "\$"+$x.text+"."+$y.text);
				label = $x.text;
			}
		}
		ST st;
		Rule refdRule = grammar.getRule(refdRuleName);
		AttributeScope scope = refdRule.getLocalAttributeScope($y.text);
		if ( scope.isPredefinedRuleScope ) {
			st = template("ruleLabelPropertyRef_"+$y.text);
			grammar.referenceRuleLabelPredefinedAttribute(refdRuleName);
			st.add("scope", label);
			st.add("attr", $y.text);
		}
		else if ( scope.isPredefinedLexerRuleScope ) {
			st = template("lexerRuleLabelPropertyRef_"+$y.text);
			grammar.referenceRuleLabelPredefinedAttribute(refdRuleName);
			st.add("scope", label);
			st.add("attr", $y.text);
		}
		else if ( scope.isParameterScope ) {
			// TODO: error!
		}
		else {
			st = template("ruleLabelRef");
			st.add("referencedRule", refdRule);
			st.add("scope", label);
			st.add("attr", scope.getAttribute($y.text));
		}
		}
	;


/** $label	either a token label or token/rule list label like label+=expr */
LABEL_REF
	:	'$' ID {enclosingRule!=null &&
	            getElementLabel($ID.text)!=null &&
		        enclosingRule.getRuleLabel($ID.text)==null}?
		// {System.out.println("found \$label");}
		{
		ST st;
		Grammar.LabelElementPair pair = getElementLabel($ID.text);
		if ( pair.type==Grammar.RULE_LIST_LABEL ||
             pair.type==Grammar.TOKEN_LIST_LABEL ||
             pair.type==Grammar.WILDCARD_TREE_LIST_LABEL )
        {
			st = template("listLabelRef");
		}
		else {
			st = template("tokenLabelRef");
		}
		st.add("label", $ID.text);
		}
	;

/** $tokenref in a non-lexer grammar */
ISOLATED_TOKEN_REF
	:	'$' ID	{grammar.type!=Grammar.LEXER && enclosingRule!=null && isTokenRefInAlt($ID.text)}?
		//{System.out.println("found \$tokenref");}
		{
		String label = enclosingRule.getElementLabel($ID.text, outerAltNum, generator);
		checkElementRefUniqueness($ID.text, true);
		if ( label==null ) {
			ErrorManager.grammarError(ErrorManager.MSG_FORWARD_ELEMENT_REF,
									  grammar,
									  actionToken,
									  $ID.text);
		}
		else {
			ST st = template("tokenLabelRef");
			st.add("label", label);
		}
		}
	;

/** $lexerruleref from within the lexer */
ISOLATED_LEXER_RULE_REF
	:	'$' ID	{grammar.type==Grammar.LEXER &&
	             enclosingRule!=null &&
	             isRuleRefInAlt($ID.text)}?
		//{System.out.println("found \$lexerruleref");}
		{
		String label = enclosingRule.getElementLabel($ID.text, outerAltNum, generator);
		checkElementRefUniqueness($ID.text, false);
		if ( label==null ) {
			ErrorManager.grammarError(ErrorManager.MSG_FORWARD_ELEMENT_REF,
									  grammar,
									  actionToken,
									  $ID.text);
		}
		else {
			ST st = template("lexerRuleLabel");
			st.add("label", label);
		}
		}
	;

/**  $y 	return value, parameter, predefined rule property, or token/rule
 *          reference within enclosing rule's outermost alt.
 *          y must be a "local" reference; i.e., it must be referring to
 *          something defined within the enclosing rule.
 *
 * 			r[int i] returns [int j]
 * 				:	{$i, $j, $start, $stop, $st, $tree}
 *              ;
 *
 *	TODO: this might get the dynamic scope's elements too.!!!!!!!!!
 */
SET_LOCAL_ATTR
	:	'$' ID WS? '=' expr=ATTR_VALUE_EXPR ';' {enclosingRule!=null
													&& enclosingRule.getLocalAttributeScope($ID.text)!=null
													&& !enclosingRule.getLocalAttributeScope($ID.text).isPredefinedLexerRuleScope}?
		//{System.out.println("found set \$localattr");}
		{
		ST st;
		AttributeScope scope = enclosingRule.getLocalAttributeScope($ID.text);
		if ( scope.isPredefinedRuleScope ) {
			if ($ID.text.equals("tree") || $ID.text.equals("st")) {
				st = template("ruleSetPropertyRef_"+$ID.text);
				grammar.referenceRuleLabelPredefinedAttribute(enclosingRule.name);
				st.add("scope", enclosingRule.name);
				st.add("attr", $ID.text);
				st.add("expr", translateAction($expr.text));
			} else {
				ErrorManager.grammarError(ErrorManager.MSG_WRITE_TO_READONLY_ATTR,
										 grammar,
										 actionToken,
										 $ID.text,
										 "");
			}
		}
		else if ( scope.isParameterScope ) {
			st = template("parameterSetAttributeRef");
			st.add("attr", scope.getAttribute($ID.text));
			st.add("expr", translateAction($expr.text));
		}
		else {
			st = template("returnSetAttributeRef");
			st.add("ruleDescriptor", enclosingRule);
			st.add("attr", scope.getAttribute($ID.text));
			st.add("expr", translateAction($expr.text));
			}
		}
	;
LOCAL_ATTR
	:	'$' ID {enclosingRule!=null && enclosingRule.getLocalAttributeScope($ID.text)!=null}?
		//{System.out.println("found \$localattr");}
		{
		ST st;
		AttributeScope scope = enclosingRule.getLocalAttributeScope($ID.text);
		if ( scope.isPredefinedRuleScope ) {
			st = template("rulePropertyRef_"+$ID.text);
			grammar.referenceRuleLabelPredefinedAttribute(enclosingRule.name);
			st.add("scope", enclosingRule.name);
			st.add("attr", $ID.text);
		}
		else if ( scope.isPredefinedLexerRuleScope ) {
			st = template("lexerRulePropertyRef_"+$ID.text);
			st.add("scope", enclosingRule.name);
			st.add("attr", $ID.text);
		}
		else if ( scope.isParameterScope ) {
			st = template("parameterAttributeRef");
			st.add("attr", scope.getAttribute($ID.text));
		}
		else {
			st = template("returnAttributeRef");
			st.add("ruleDescriptor", enclosingRule);
			st.add("attr", scope.getAttribute($ID.text));
		}
		}
	;

/**	$x::y	the only way to access the attributes within a dynamic scope
 * 			regardless of whether or not you are in the defining rule.
 *
 * 			scope Symbols { List names; }
 * 			r
 * 			scope {int i;}
 * 			scope Symbols;
 * 				:	{$r::i=3;} s {$Symbols::names;}
 * 				;
 * 			s	:	{$r::i; $Symbols::names;}
 * 				;
 */
SET_DYNAMIC_SCOPE_ATTR
	:	'$' x=ID '::' y=ID WS? '=' expr=ATTR_VALUE_EXPR ';'
						   {resolveDynamicScope($x.text)!=null &&
						     resolveDynamicScope($x.text).getAttribute($y.text)!=null}?
		//{System.out.println("found set \$scope::attr "+ $x.text + "::" + $y.text + " to " + $expr.text);}
		{
		AttributeScope scope = resolveDynamicScope($x.text);
		if ( scope!=null ) {
			ST st = template("scopeSetAttributeRef");
			st.add("scope", $x.text);
			st.add("attr",  scope.getAttribute($y.text));
			st.add("expr",  translateAction($expr.text));
		}
		else {
			// error: invalid dynamic attribute
		}
		}
	;

DYNAMIC_SCOPE_ATTR
	:	'$' x=ID '::' y=ID
						   {resolveDynamicScope($x.text)!=null &&
						     resolveDynamicScope($x.text).getAttribute($y.text)!=null}?
		//{System.out.println("found \$scope::attr "+ $x.text + "::" + $y.text);}
		{
		AttributeScope scope = resolveDynamicScope($x.text);
		if ( scope!=null ) {
			ST st = template("scopeAttributeRef");
			st.add("scope", $x.text);
			st.add("attr",  scope.getAttribute($y.text));
		}
		else {
			// error: invalid dynamic attribute
		}
		}
	;


ERROR_SCOPED_XY
	:	'$' x=ID '::' y=ID
		{
		chunks.add(getText());
		generator.issueInvalidScopeError($x.text,$y.text,
		                                 enclosingRule,actionToken,
		                                 outerAltNum);		
		}
	;
	
/**		To access deeper (than top of stack) scopes, use the notation:
 *
 * 		$x[-1]::y previous (just under top of stack)
 * 		$x[-i]::y top of stack - i where the '-' MUST BE PRESENT;
 * 				  i.e., i cannot simply be negative without the '-' sign!
 * 		$x[i]::y  absolute index i (0..size-1)
 * 		$x[0]::y  is the absolute 0 indexed element (bottom of the stack)
 */
DYNAMIC_NEGATIVE_INDEXED_SCOPE_ATTR
	:	'$' x=ID '[' '-' expr=SCOPE_INDEX_EXPR ']' '::' y=ID
		// {System.out.println("found \$scope[-...]::attr");}
		{
		ST st = template("scopeAttributeRef");
		st.add("scope",    $x.text);
		st.add("attr",     resolveDynamicScope($x.text).getAttribute($y.text));
		st.add("negIndex", $expr.text);
		}		
	;

DYNAMIC_ABSOLUTE_INDEXED_SCOPE_ATTR
	:	'$' x=ID '[' expr=SCOPE_INDEX_EXPR ']' '::' y=ID 
		// {System.out.println("found \$scope[...]::attr");}
		{
		ST st = template("scopeAttributeRef");
		st.add("scope", $x.text);
		st.add("attr",  resolveDynamicScope($x.text).getAttribute($y.text));
		st.add("index", $expr.text);
		}		
	;

fragment
SCOPE_INDEX_EXPR
	:	(~']')+
	;
	
/** $r		y is a rule's dynamic scope or a global shared scope.
 * 			Isolated $rulename is not allowed unless it has a dynamic scope *and*
 * 			there is no reference to rulename in the enclosing alternative,
 * 			which would be ambiguous.  See TestAttributes.testAmbiguousRuleRef()
 */
ISOLATED_DYNAMIC_SCOPE
	:	'$' ID {resolveDynamicScope($ID.text)!=null}?
		// {System.out.println("found isolated \$scope where scope is a dynamic scope");}
		{
		ST st = template("isolatedDynamicScopeRef");
		st.add("scope", $ID.text);
		}		
	;
	
// antlr.g then codegen.g does these first two currently.
// don't want to duplicate that code.

/** %foo(a={},b={},...) ctor */
TEMPLATE_INSTANCE
	:	'%' ID '(' ( WS? ARG (',' WS? ARG)* WS? )? ')'
		// {System.out.println("found \%foo(args)");}
		{
		String action = getText().substring(1,getText().length());
		String ruleName = "<outside-of-rule>";
		if ( enclosingRule!=null ) {
			ruleName = enclosingRule.name;
		}
		ST st =
			generator.translateTemplateConstructor(ruleName,
												   outerAltNum,
												   actionToken,
												   action);
		if ( st!=null ) {
			chunks.add(st);
		}
		}
	;

/** %({name-expr})(a={},...) indirect template ctor reference */
INDIRECT_TEMPLATE_INSTANCE
	:	'%' '(' ACTION ')' '(' ( WS? ARG (',' WS? ARG)* WS? )? ')'
		// {System.out.println("found \%({...})(args)");}
		{
		String action = getText().substring(1,getText().length());
		ST st =
			generator.translateTemplateConstructor(enclosingRule.name,
												   outerAltNum,
												   actionToken,
												   action);
		chunks.add(st);
		}
	;

fragment
ARG	:	ID '=' ACTION
	;

/**	%{expr}.y = z; template attribute y of ST-typed expr to z */
SET_EXPR_ATTRIBUTE
	:	'%' a=ACTION '.' ID WS? '=' expr=ATTR_VALUE_EXPR ';'
		// {System.out.println("found \%{expr}.y = z;");}
		{
		ST st = template("actionSetAttribute");
		String action = $a.text;
		action = action.substring(1,action.length()-1); // stuff inside {...}
		st.add("st", translateAction(action));
		st.add("attrName", $ID.text);
		st.add("expr", translateAction($expr.text));
		}
	;
	
/*    %x.y = z; set template attribute y of x (always set never get attr)
 *              to z [languages like python without ';' must still use the
 *              ';' which the code generator is free to remove during code gen]
 */
SET_ATTRIBUTE
	:	'%' x=ID '.' y=ID WS? '=' expr=ATTR_VALUE_EXPR ';'
		// {System.out.println("found \%x.y = z;");}
		{
		ST st = template("actionSetAttribute");
		st.add("st", $x.text);
		st.add("attrName", $y.text);
		st.add("expr", translateAction($expr.text));
		}
	;

/** Don't allow an = as first char to prevent $x == 3; kind of stuff. */
fragment
ATTR_VALUE_EXPR
	:	~'=' (~';')*
	;
	
/** %{string-expr} anonymous template from string expr */
TEMPLATE_EXPR
	:	'%' a=ACTION
		// {System.out.println("found \%{expr}");}
		{
		ST st = template("actionStringConstructor");
		String action = $a.text;
		action = action.substring(1,action.length()-1); // stuff inside {...}
		st.add("stringExpr", translateAction(action));
		}
	;
	
fragment
ACTION
	:	'{' (options {greedy=false;}:.)* '}'
	;
	
ESC :   '\\' '$' {chunks.add("\$");}
	|	'\\' '%' {chunks.add("\%");}
	|	'\\' ~('$'|'%') {chunks.add(getText());}
    ;       

ERROR_XY
	:	'$' x=ID '.' y=ID
		{
		chunks.add(getText());
		generator.issueInvalidAttributeError($x.text,$y.text,
		                                     enclosingRule,actionToken,
		                                     outerAltNum);
		}
	;
	
ERROR_X
	:	'$' x=ID
		{
		chunks.add(getText());
		generator.issueInvalidAttributeError($x.text,
		                                     enclosingRule,actionToken,
		                                     outerAltNum);
		}
	;
	
UNKNOWN_SYNTAX
	:	'$'
		{
		chunks.add(getText());
		// shouldn't need an error here.  Just accept \$ if it doesn't look like anything
		}
	|	'%' (ID|'.'|'('|')'|','|'{'|'}'|'"')*
		{
		chunks.add(getText());
		ErrorManager.grammarError(ErrorManager.MSG_INVALID_TEMPLATE_ACTION,
								  grammar,
								  actionToken,
								  getText());
		}
	;

TEXT:	~('$'|'%'|'\\')+ {chunks.add(getText());}
	;
	
fragment
ID  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*
    ;

fragment
INT :	'0'..'9'+
	;

fragment
WS	:	(' '|'\t'|'\n'|'\r')+
	;
