/* Structured Pattern Defintion Language V0.1 Hao Xu */ grammar simplespdl; options{k=2;output=AST;} tokens { CLASS; FIELD; ABSTRACTMETHOD; METHOD; METHODSIGNATURE; PATTERN; LIST; INTEGER; BOOLEAN; STRING; ANY; COLLECTION; STATEMENTS; METHODBODY; ASSIGNMENT; VARIABLEDEFINITION; RETURN; LOOP; METHODINVOCATION; THIS; NEW; SUPER; CONST; VARIABLE; INTEGERLITERAL; BOOLEANLITERAL; STRINGLITERAL; EXP; IMPE; IDENTIFIER; QUANTIFY; ESCAPE; IMPA; IMPES; UNION; INTERSECTION; NOSTATEMENT; EMPTYLIST; } @header{ package spdl; } @lexer::header { package spdl; } prog : patternd+; patternd : 'pattern' ID ('(' partlist ')')? ('extends' patternlist)? '{' cd* '}' -> ^(PATTERN ID partlist patternlist cd); partlist : part (','part)* -> ^(LIST part); part : a; patternlist : pattern (','pattern)*; pattern : ID ('(' partlist ')')?; cd : 'classa' classa ('extends' classlist ')')? '{' md* '}' -> ^(CLASS classa classlist md); md : 'field' t field';' -> ^(FIELD t field) | 'abstract' 'method' ms';' -> ^(ABSTRACTMETHOD ms) | 'method' ms mbody -> ^(METHOD ms mbody); ms : t method '(' pd ')'->^(METHODSIGNATURE t method pd); pd : '*'->^(ANY) | ((ts+=t ID) (','ts+=t ID)*)?->{$ts==null}?^(EMPTYLIST)->^(LIST t ID); t : '*' ->^(ANY) | 'int' ->^(INTEGER) | 'boolean' ->^(BOOLEAN) | 'String' ->^(STRING) | classa ->^(CLASS classa) | 'collection' '<' t '>' ->^(COLLECTION t); mbody : '{' ss? '}'->^(METHODBODY ss); s : ID '=' e';' ->^(ASSIGNMENT ID e) | t ID';' ->^(VARIABLEDEFINITION t ID) | 'return' e';' ->^(RETURN e) | 'for' '(' t ID ':' e ')' '{' ss '}' ->^(LOOP t ID e ss); ss : (stats+=s)* -> {$stats==null}? ^(NOSTATEMENT) ->^(STATEMENTS s); expnmi : | '(' exp ')' -> exp | 'this' -> ^(THIS) | 'new' classa '(' args ')' ->^(NEW classa args) | 'super' mi ->^(SUPER mi) | consta -> ^(CONST consta) ; exp : expnmi ml+=mi* -> {$ml==null}? expnmi ->^(EXP expnmi mi); mi : '.'method('('args')')? -> ^(METHODINVOCATION method args); consta : e ->^(VARIABLE e) | INT ->^(INTEGERLITERAL INT) | BOOL ->^(BOOLEANLITERAL BOOL) | STR ->^(STRINGLITERAL STR); classa : e; field : e; method : e; classlist : classa (','classa)* -> ^(LIST classa); args : '*'|(exp(','exp)*)? ->^(LIST exp); e : id ('[' 'some' ind+=e ']')* ->{$ind==null}? ^(IMPE id) -> ^(IMPES id $ind); id : ID ->^(IDENTIFIER ID) | '!' id ->^(QUANTIFY id) | '~!' id -> ^(ESCAPE id); a : e ('&'e)* ->^(IMPA e); LETTER : 'a'..'z'|'A'..'Z'; DIGIT : '0'..'9'; SIGN : '+'|'-'; ID : (LETTER|'_')(LETTER|DIGIT|'_')*; INT : SIGN? DIGIT+; BOOL : 'true'|'false'; STR : '"' ('\\\\'|'\\"'|~('\\'|'"'))* ; NEWLINE : '\r'? '\n' {skip();}; WS : (' '|'\t')+ {skip();};