// This file was generated by DAJ from program.cd. header { import edu.neu.ccs.demeter.*; } class programParser extends Parser; options { // DAJ options for Parser defaultErrorHandler=false; } { static char unescapifyChar(String s) { char c = s.charAt(0); if (c == '\\') { switch (s.charAt(1)) { case 'n': c = '\n'; break; case 't': c = '\t'; break; case 'b': c = '\b'; break; case 'r': c = '\r'; break; case 'f': c = '\f'; break; case '\\': c = '\\'; break; case '\'': c = '\''; break; case '\"': c = '\"'; break; default: c = (char) Integer.parseInt(s.substring(1, s.length()), 8); break; } } return c; } static String unescapify(String s) { char str[] = new char[s.length()]; int i = 0, o = 0; while (i < s.length()) { char c = s.charAt(i++); if (c == '\\') { int j = i + 1; while (j < s.length() && Character.digit(s.charAt(j), 8) != -1) { j++; } c = unescapifyChar(s.substring(i-1, j)); i = j; } str[o++] = c; } return String.valueOf(str, 0, o); } } parseChineseWallPolicyChecker returns [ChineseWallPolicyChecker it] { it = new ChineseWallPolicyChecker(); ChineseWallAutomaton_List the_chineseWallAutomaton_List = null; } : the_chineseWallAutomaton_List=parseChineseWallAutomaton_List { it.chineseWallAutomaton_List = the_chineseWallAutomaton_List; } EOF ; parseChineseWallAutomaton returns [ChineseWallAutomaton it] { it = new ChineseWallAutomaton(); AutomatonName the_automatonName = null; State the_currentState = null; State the_startState = null; Transition_List the_transition = null; Group_List the_groups = null; CIType_List the_citypes = null; Access_List the_history = null; } : "Chinese" "Wall" "automaton" the_automatonName=parseAutomatonName { it.automatonName = the_automatonName; } "currentState" the_currentState=parseState { it.currentState = the_currentState; } ( "startState" the_startState=parseState { it.startState = the_startState; } )? ( "transitions" the_transition=parseTransition_List { it.transition = the_transition; } )? "groups" the_groups=parseGroup_List { it.groups = the_groups; } "citypes" the_citypes=parseCIType_List { it.citypes = the_citypes; } "history" the_history=parseAccess_List { it.history = the_history; } ; parseState returns [State it] { it = new State(); Group_List the_g_accesses = null; CIType_List the_t_accesses = null; } : the_g_accesses=parseGroup_List { it.g_accesses = the_g_accesses; } the_t_accesses=parseCIType_List { it.t_accesses = the_t_accesses; } ; parseAccess returns [Access it] { it = new Access(); ObjektId the_objektId = null; Group the_group = null; } : the_objektId=parseObjektId { it.objektId = the_objektId; } "group" the_group=parseGroup { it.group = the_group; } ; parseGroup returns [Group it] { it = new Group(); GroupName the_groupName = null; CIType the_cIType = null; } : the_groupName=parseGroupName { it.groupName = the_groupName; } ( "citype" the_cIType=parseCIType { it.cIType = the_cIType; } )? ; parseCIType returns [CIType it] { it = new CIType(); CITypeName the_cITypeName = null; } : the_cITypeName=parseCITypeName { it.cITypeName = the_cITypeName; } ; parseTransition returns [Transition it] { it = new Transition(); Access the_newAccess = null; } : the_newAccess=parseAccess { it.newAccess = the_newAccess; } ; parseObjektId returns [ObjektId it] { it = new ObjektId(); Ident the_ident = null; } : the_ident=parseIdent { it.ident = the_ident; } ; parseGroupName returns [GroupName it] { it = new GroupName(); Ident the_ident = null; } : the_ident=parseIdent { it.ident = the_ident; } ; parseCITypeName returns [CITypeName it] { it = new CITypeName(); Ident the_ident = null; } : the_ident=parseIdent { it.ident = the_ident; } ; parseAutomatonName returns [AutomatonName it] { it = new AutomatonName(); Ident the_ident = null; } : the_ident=parseIdent { it.ident = the_ident; } ; parseChineseWallAutomaton_List returns [ChineseWallAutomaton_List it] { it = new ChineseWallAutomaton_List(); ChineseWallAutomaton the_repeatedPart = null; } : "(" ( the_repeatedPart=parseChineseWallAutomaton { it.add(the_repeatedPart); } )* ")" ; parseTransition_List returns [Transition_List it] { it = new Transition_List(); Transition the_repeatedPart = null; } : "(" ( the_repeatedPart=parseTransition { it.add(the_repeatedPart); } )* ")" ; parseGroup_List returns [Group_List it] { it = new Group_List(); Group the_repeatedPart = null; } : "(" ( the_repeatedPart=parseGroup { it.add(the_repeatedPart); } )* ")" ; parseCIType_List returns [CIType_List it] { it = new CIType_List(); CIType the_repeatedPart = null; } : "(" ( the_repeatedPart=parseCIType { it.add(the_repeatedPart); } )* ")" ; parseAccess_List returns [Access_List it] { it = new Access_List(); Access the_repeatedPart = null; } : "(" ( the_repeatedPart=parseAccess { it.add(the_repeatedPart); } )* ")" ; parseboolean returns [boolean it] : "true" { it = true; } | "false" { it = false; } ; parsechar returns [char it] : t:CHAR_LITERAL { String s = t.getText(); it = unescapifyChar(s.substring(1, s.length()-1)); } ; parsebyte returns [byte it] { int i; } : i=parseint { it = (byte) i; } ; parseshort returns [short it] { int i; } : i=parseint { it = (short) i; } ; parseint returns [int it] : t:NUM_INT { it = Integer.parseInt(t.getText()); } ; parselong returns [long it] : t:NUM_LONG { String s = t.getText(); it = Long.parseLong(s.substring(0,s.length()-1)); } ; parsefloat returns [float it] : t:NUM_FLOAT { String s = t.getText(); it = Float.parseFloat(s.substring(0,s.length()-1)); } ; parsedouble returns [double it] : t:NUM_DOUBLE { String s = t.getText(); if (s.endsWith("D") || s.endsWith("d")) it = Double.parseDouble(s.substring(0,s.length()-1)); else it = Double.parseDouble(s); } ; parseBoolean returns [Boolean it] : "true" { it = Boolean.TRUE; } | "false" { it = Boolean.FALSE; } ; parseCharacter returns [Character it] { char c; } : c=parsechar { it = new Character(c); } ; parseByte returns [Byte it] { byte b; } : b=parsebyte { it = new Byte(b); } ; parseInteger returns [Integer it] { int i; } : i=parseint { it = new Integer(i); } ; parseLong returns [Long it] { long l; } : l=parselong { it = new Long(l); } ; parseFloat returns [Float it] { float f; } : f=parsefloat { it = new Float(f); } ; parseDouble returns [Double it] { double d; } : d=parsedouble { it = new Double(d); } ; parseNumber returns [Number it] : it=parseInteger | it=parseLong | it=parseFloat | it=parseDouble ; parseString returns [String it] : t:STRING_LITERAL { String s = t.getText(); it = unescapify(s.substring(1, s.length()-1)); } ; parseIdent returns [Ident it] : t:IDENT { it = new Ident(t.getText()); } ; class programLexer extends Lexer; options { // Default Lexer Options k=2; testLiterals=false; charVocabulary='\u0003'..'\uFFFF'; codeGenBitsetTestThreshold=20; defaultErrorHandler=false; } tokens { DOT; } IDENT options { testLiterals=true; }: ("(") => "(" | (")") => ")" | ('a'..'z'|'A'..'Z'|'_'|'$') ('a'..'z'|'A'..'Z'|'_'|'0'..'9'|'$')* ; // Mostly copied from JavaLexer in antlr/examples/java/java/java.g: // Exception: NUM_INT, added a sub-option to first choice to deal with "." // Whitespace -- ignored WS : ( ' ' | '\t' | '\f' // handle newlines | ( options {generateAmbigWarnings=false;} : "\r\n" // Evil DOS | '\r' // Macintosh | '\n' // Unix (the right way) ) { newline(); } )+ { _ttype = Token.SKIP; } ; // Single-line comments SL_COMMENT : "//" (~('\n'|'\r'))* ('\n'|'\r'('\n')?) {$setType(Token.SKIP); newline();} ; // multiple-line comments ML_COMMENT : "/*" ( /* '\r' '\n' can be matched in one alternative or by matching '\r' in one iteration and '\n' in another. I am trying to handle any flavor of newline that comes in, but the language that allows both "\r\n" and "\r" and "\n" to all be valid newline is ambiguous. Consequently, the resulting grammar must be ambiguous. I'm shutting this warning off. */ options { generateAmbigWarnings=false; } : { LA(2)!='/' }? '*' | '\r' '\n' {newline();} | '\r' {newline();} | '\n' {newline();} | ~('*'|'\n'|'\r') )* "*/" {$setType(Token.SKIP);} ; // character literals CHAR_LITERAL : '\'' ( ESC | ~'\'' ) '\'' ; // string literals STRING_LITERAL : '"' (ESC|~('"'|'\\'))* '"' ; // escape sequence -- note that this is protected; it can only be called // from another lexer rule -- it will not ever directly return a token to // the parser // There are various ambiguities hushed in this rule. The optional // '0'...'9' digit matches should be matched here rather than letting // them go back to STRING_LITERAL to be matched. ANTLR does the // right thing by matching immediately; hence, it's ok to shut off // the FOLLOW ambig warnings. protected ESC : '\\' ( 'n' | 'r' | 't' | 'b' | 'f' | '"' | '\'' | '\\' | ('u')+ HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT | '0'..'3' ( options { warnWhenFollowAmbig = false; } : '0'..'7' ( options { warnWhenFollowAmbig = false; } : '0'..'7' )? )? | '4'..'7' ( options { warnWhenFollowAmbig = false; } : '0'..'7' )? ) ; // hexadecimal digit (again, note it's protected!) protected HEX_DIGIT : ('0'..'9'|'A'..'F'|'a'..'f') ; // a dummy rule to force vocabulary to be all characters (except special // ones that ANTLR uses internally (0 to 2) protected VOCAB : '\3'..'\377' ; // a numeric literal NUM_INT options {testLiterals=true;} // needed to match "." as an IDENT {boolean isDecimal=false; Token t=null;} : '.' {_ttype = DOT;} ( ( ('0'..'9')+ (EXPONENT)? (f1:FLOAT_SUFFIX {t=f1;})? { if (t != null && t.getText().toUpperCase().indexOf('F')>=0) { _ttype = NUM_FLOAT; } else { _ttype = NUM_DOUBLE; // assume double } } )? | ('a'..'z'|'A'..'Z'|'_'|'$') ('a'..'z'|'A'..'Z'|'_'|'0'..'9'|'$')* { _ttype=IDENT;} // "." ==> IDENT ) | ( '0' {isDecimal = true;} // special case for just '0' ( ('x'|'X') ( // hex // the 'e'|'E' and float suffix stuff look // like hex digits, hence the (...)+ doesn't // know when to stop: ambig. ANTLR resolves // it correctly by matching immediately. It // is therefor ok to hush warning. options { warnWhenFollowAmbig=false; } : HEX_DIGIT )+ | ('0'..'7')+ // octal )? | ('1'..'9') ('0'..'9')* {isDecimal=true;} // non-zero decimal ) ( ('l'|'L') { _ttype = NUM_LONG; } // only check to see if it's a float if looks like decimal so far | {isDecimal}? ( '.' ('0'..'9')* (EXPONENT)? (f2:FLOAT_SUFFIX {t=f2;})? | EXPONENT (f3:FLOAT_SUFFIX {t=f3;})? | f4:FLOAT_SUFFIX {t=f4;} ) { if (t != null && t.getText().toUpperCase() .indexOf('F') >= 0) { _ttype = NUM_FLOAT; } else { _ttype = NUM_DOUBLE; // assume double } } )? ; // a couple protected methods to assist in matching floating point numbers protected EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ; protected FLOAT_SUFFIX : 'f'|'F'|'d'|'D' ;