All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
antlr.actions.csharp.action.g Maven / Gradle / Ivy
header {
package antlr.actions.csharp;
}
{
import java.io.StringReader;
import antlr.collections.impl.Vector;
import antlr.*;
}
/* ANTLR Translator Generator
* Project led by Terence Parr at http://www.cs.usfca.edu
* Software rights: http://www.antlr.org/license.html
*
* Port to C# by Kunle Odutola : kunle UNDERSCORE odutola AT hotmail DOT com
*
* $Id:$
*/
// HISTORY:
//
// 01-Aug-2002 kunle Now handles C# preprocessor directives
// [ Based on Ric's C/C++ preprocessor code ]
// 07-Dec-2002 kunle Now supports the new #[ID,text,nodeType] syntax.
//
/** Perform the following translations:
AST related translations
## -> currentRule_AST
#(x,y,z) -> codeGenerator.getASTCreateString(vector-of(x,y,z))
#[x] -> codeGenerator.getASTCreateString(x)
#x -> codeGenerator.mapTreeId(x)
Inside context of #(...), you can ref (x,y,z), [x], and x as shortcuts.
Text related translations
$append(x) -> text.append(x)
$setText(x) -> text.setLength(_begin); text.append(x)
$getText -> new String(text.getBuffer(),_begin,text.length()-_begin)
$setToken(x) -> _token = x
$setType(x) -> _ttype = x
$FOLLOW(r) -> FOLLOW set name for rule r (optional arg)
$FIRST(r) -> FIRST set name for rule r (optional arg)
*/
class ActionLexer extends Lexer;
options {
k=3;
charVocabulary='\3'..'\377';
testLiterals=false;
interactive=true;
}
{
protected RuleBlock currentRule;
protected CodeGenerator generator;
protected int lineOffset = 0;
private Tool antlrTool; // The ANTLR tool
ActionTransInfo transInfo;
public ActionLexer( String s, RuleBlock currentRule,
CodeGenerator generator,
ActionTransInfo transInfo )
{
this(new StringReader(s));
this.currentRule = currentRule;
this.generator = generator;
this.transInfo = transInfo;
}
public void setLineOffset(int lineOffset)
{
setLine(lineOffset);
}
public void setTool(Tool tool)
{
this.antlrTool = tool;
}
public void reportError(RecognitionException e)
{
antlrTool.error("Syntax error in action: "+e,getFilename(),getLine(),getColumn());
}
public void reportError(String s)
{
antlrTool.error(s,getFilename(),getLine(),getColumn());
}
public void reportWarning(String s)
{
if ( getFilename()==null )
antlrTool.warning(s);
else
antlrTool.warning(s,getFilename(),getLine(),getColumn());
}
}
// rules are protected because we don't care about nextToken().
public
ACTION
: ( STUFF
| AST_ITEM
| TEXT_ITEM
)+
;
/** stuff in between #(...) and #id items
* Allow the escaping of the # for C# preprocessor stuff.
*/
protected
STUFF
: COMMENT
| STRING
| CHAR
| "\r\n" { newline(); }
| '\\' '#' { $setText("#"); }
| '\r' { newline(); }
| '\n' { newline(); }
| '/' ~('/'|'*') // non-comment start '/'
// | ( ~('/'|'\n'|'\r'|'$'|'#'|'"'|'\'') )+
| ~('/'|'\n'|'\r'|'$'|'#'|'"'|'\'')
;
protected
AST_ITEM
: '#'! t:TREE // #( )
| '#'! (WS)? id:ID // #a_name (=)?
{
String idt = id.getText();
String mapped = generator.mapTreeId(id.getText(), transInfo);
// verify that it's not a preprocessor macro...
if ( (mapped != null) && !idt.equals(mapped) )
{
$setText(mapped);
}
else
{
if (idt.equals("define") ||
idt.equals("undef") ||
idt.equals("if") ||
idt.equals("elif") ||
idt.equals("else") ||
idt.equals("endif") ||
idt.equals("line") ||
idt.equals("error") ||
idt.equals("warning") ||
idt.equals("region") ||
idt.equals("endregion"))
{
$setText("#"+idt);
}
}
}
(WS)?
( options {greedy=true;} : VAR_ASSIGN )?
| '#'! ctor:AST_CONSTRUCTOR // #[ ]
| "##"
{
if( currentRule != null )
{
String r = currentRule.getRuleName()+"_AST";
$setText(r);
if ( transInfo!=null ) {
transInfo.refRuleRoot=r; // we ref root of tree
}
}
else
{
reportWarning("\"##\" not valid in this context");
$setText("##");
}
}
(WS)?
( options {greedy=true;} : VAR_ASSIGN )?
;
protected
TEXT_ITEM
: "$append" (WS)? '(' a1:TEXT_ARG ')'
{
String t = "text.Append("+a1.getText()+")";
$setText(t);
}
| "$set"
( "Text" (WS)? '(' a2:TEXT_ARG ')'
{
String t;
t = "text.Length = _begin; text.Append("+a2.getText()+")";
$setText(t);
}
| "Token" (WS)? '(' a3:TEXT_ARG ')'
{
String t="_token = "+a3.getText();
$setText(t);
}
| "Type" (WS)? '(' a4:TEXT_ARG ')'
{
String t="_ttype = "+a4.getText();
$setText(t);
}
)
| "$getText"
{
$setText("text.ToString(_begin, text.Length-_begin)");
}
| "$FOLLOW" ( (WS)? '(' a5:TEXT_ARG ')' )?
{
String rule = currentRule.getRuleName();
if ( a5!=null ) {
rule = a5.getText();
}
String setName = generator.getFOLLOWBitSet(rule, 1);
// System.out.println("FOLLOW("+rule+")="+setName);
if ( setName==null ) {
reportError("$FOLLOW("+rule+")"+
": unknown rule or bad lookahead computation");
}
else {
$setText(setName);
}
}
| "$FIRST" ( (WS)? '(' a6:TEXT_ARG ')' )?
{
String rule = currentRule.getRuleName();
if ( a6!=null ) {
rule = a6.getText();
}
String setName = generator.getFIRSTBitSet(rule, 1);
// System.out.println("FIRST("+rule+")="+setName);
if ( setName==null ) {
reportError("$FIRST("+rule+")"+
": unknown rule or bad lookahead computation");
}
else {
$setText(setName);
}
}
;
protected
TREE!
{
StringBuffer buf = new StringBuffer();
int n=0;
Vector terms = new Vector(10);
}
: '('
(WS)?
t:TREE_ELEMENT
{
terms.appendElement(
generator.processStringForASTConstructor(t.getText())
);
}
(WS)?
( ',' (WS)?
t2:TREE_ELEMENT
{
terms.appendElement(
generator.processStringForASTConstructor(t2.getText())
);
}
(WS)?
)*
{$setText(generator.getASTCreateString(terms));}
')'
;
protected
TREE_ELEMENT { boolean was_mapped; }
: '#'! TREE
| '#'! AST_CONSTRUCTOR
| '#'! was_mapped=id:ID_ELEMENT
{ // RK: I have a queer feeling that this maptreeid is redundant..
if ( ! was_mapped )
{
String t = generator.mapTreeId(id.getText(), null);
if ( t!=null ) {
$setText(t);
}
}
}
| "##"
{
if( currentRule != null )
{
String t = currentRule.getRuleName()+"_AST";
$setText(t);
}
else
{
reportError("\"##\" not valid in this context");
$setText("##");
}
}
| TREE
| AST_CONSTRUCTOR
| ID_ELEMENT
| STRING
;
// FIXME: RK - the getASTCreateString here is broken.
// getASTCreateString can not cleanly see if a constructor like
// tokens { FOR; }
// forLoop:! "for" bla bla
// { #forLoop = #([FOR,"for"], bla bla ) }
// should use ForNode as AST.
//
protected
AST_CONSTRUCTOR!
: '[' (WS)? x:AST_CTOR_ELEMENT (WS)?
(',' (WS)? y:AST_CTOR_ELEMENT (WS)? )?
(',' (WS)? z:AST_CTOR_ELEMENT (WS)? )? ']'
{
String args = generator.processStringForASTConstructor(x.getText());
// the second does not need processing coz it's a string
// (eg second param of astFactory.create(x,y)
if ( y!=null )
args += ","+y.getText();
if ( z!=null )
args += ","+z.getText();
$setText(generator.getASTCreateString(null,args));
}
;
/** The arguments of a #[...] constructor are text, token type,
* or a tree.
*/
protected
AST_CTOR_ELEMENT
: STRING
| INT
| TREE_ELEMENT
;
/** An ID_ELEMENT can be a func call, array ref, simple var,
* or AST label ref.
*/
protected
ID_ELEMENT returns [boolean mapped=false]
: id:ID (options {greedy=true;}:WS!)?
( '(' (options {greedy=true;}:WS!)? ( ARG (',' (WS!)? ARG)* )? (WS!)? ')' // method call
| ( '[' (WS!)? ARG (WS!)? ']' )+ // array reference
| '.' ID_ELEMENT
| "->" ID_ELEMENT
| /* could be a token reference or just a user var */
{
mapped = true;
String t = generator.mapTreeId(id.getText(), transInfo);
// System.out.println("mapped: "+id.getText()+" -> "+t);
if ( t!=null ) {
$setText(t);
}
}
// if #rule referenced, check for assignment
( options {greedy=true;}
: {transInfo!=null && transInfo.refRuleRoot!=null}?
(WS)? VAR_ASSIGN
)?
)
;
protected
TEXT_ARG
: (WS)? ( TEXT_ARG_ELEMENT (options {greedy=true;}:WS)? )+
;
protected
TEXT_ARG_ELEMENT
: TEXT_ARG_ID_ELEMENT
| STRING
| CHAR
| INT_OR_FLOAT
| TEXT_ITEM
| '+'
;
protected
TEXT_ARG_ID_ELEMENT
: id:ID (options {greedy=true;}:WS!)?
( '(' (options {greedy=true;}:WS!)? ( TEXT_ARG (',' TEXT_ARG)* )* (WS!)? ')' // method call
| ( '[' (WS!)? TEXT_ARG (WS!)? ']' )+ // array reference
| '.' TEXT_ARG_ID_ELEMENT
| "->" TEXT_ARG_ID_ELEMENT
|
)
;
protected
ARG : ( TREE_ELEMENT
| STRING
| CHAR
| INT_OR_FLOAT
)
(options {greedy=true;} : (WS)? ( '+'| '-' | '*' | '/' ) (WS)? ARG )*
;
protected
ID : ('a'..'z'|'A'..'Z'|'_')
(options {greedy=true;} : ('a'..'z'|'A'..'Z'|'0'..'9'|'_'))*
;
protected
VAR_ASSIGN
: '='
{
// inform the code generator that an assignment was done to
// AST root for the rule if invoker set refRuleRoot.
if ( LA(1)!='=' && transInfo!=null && transInfo.refRuleRoot!=null ) {
transInfo.assignToRoot=true;
}
}
;
protected
COMMENT
: SL_COMMENT
| ML_COMMENT
;
protected
SL_COMMENT
: "//" (options {greedy=false;}:.)* ('\n'|"\r\n"|'\r')
{newline();}
;
protected
ML_COMMENT :
"/*"
( options {greedy=false;}
: '\r' '\n' {newline();}
| '\r' {newline();}
| '\n' {newline();}
| .
)*
"*/"
;
protected
CHAR :
'\''
( ESC | ~'\'' )
'\''
;
protected
STRING :
'"'
(ESC|~'"')*
'"'
;
protected
ESC : '\\'
( 'n'
| 'r'
| 't'
| 'b'
| 'f'
| '"'
| '\''
| '\\'
| ('0'..'3')
( options {greedy=true;}
: DIGIT
( options {greedy=true;}
: DIGIT
)?
)?
| ('4'..'7') (options {greedy=true;}:DIGIT)?
)
;
protected
DIGIT
: '0'..'9'
;
protected
INT : (DIGIT)+
;
protected
INT_OR_FLOAT
: (options {greedy=true;}:DIGIT)+
( options {greedy=true;}
: '.' (options {greedy=true;}:DIGIT)*
| 'L'
| 'l'
)?
;
protected
WS : ( options {greedy=true;}
: ' '
| '\t'
| '\r' '\n' {newline();}
| '\r' {newline();}
| '\n' {newline();}
)+
;