blob: 241652a3e7cb2b5057ba40083cad3b854a77b594 [file] [log] [blame]
-- @authors Frédéric Jouault
-- @date 2007/07/26
-- @description This TCS model defines the syntax of the ATL language.
-- REMARKS:
-- - there is a problem which requires to add the syntactic predicate:
-- (NAME LPAREN)=>
-- before:
-- ret=operationCallExp
-- when compiling with ANTLRv3
-- - k = 0 means:
-- backtrack = true;
-- for ANTLRv3
-- - disambiguation information is typically used with ANTLRv2
syntax ATL(k = 0) {
primitiveTemplate identifier for String default using NAME:
value = "%token%";
primitiveTemplate identifierOrKeyword for String using NAME orKeyword:
value = "%token%";
primitiveTemplate stringSymbol for String using STRING:
value = "ei.unescapeString(%token%, 1)",
serializer="'\'' + %value%.toCString() + '\''";
primitiveTemplate integerSymbol for Integer default using INT:
value = "Integer.valueOf(%token%)";
primitiveTemplate floatSymbol for Double default using FLOAT:
value = "Double.valueOf(%token%)";
-- @begins Units
template Unit main abstract;
template Module context
: "module" name ";" <newline>
"create" outModels{separator = ","} (isRefining ? "refining" : "from") inModels{separator = ","} ";"
[
libraries
elements
] {nbNL = 2, indentIncr = 0}
;
template Library context
: "library" name ";"
[
libraries
helpers
] {nbNL = 2, indentIncr = 0}
;
template Query context
: "query" name "=" body ";"
[
libraries
helpers
] {nbNL = 2, indentIncr = 0}
;
-- @end Units
template LibraryRef
: "uses" name ";"
;
template ModuleElement abstract;
-- @begin Helpers
template Helper
: "helper" definition ";"
;
template OclFeatureDefinition
: (isDefined(context_) ? context_) "def" <no_space> ":" feature
;
template OclContextDefinition
: "context" context_
;
template OclFeature abstract;
template Operation context
: name "(" parameters{separator = ","} ")" ":" returnType "="
[ body ] {endNL = false}
;
template Parameter addToContext
: varName ":" type
;
template Attribute
: name ":" type "="
[ initExpression ] {endNL = false}
;
-- @end Helpers
-- @begin Rules
template Rule abstract;
template MatchedRule abstract context addToContext
: (isNoDefault ? "nodefault") (isAbstract ? "abstract") (isRefining ? "refining") "rule" name (isDefined(superRule) ? "extends" superRule{refersTo = name, importContext}) "{" [
inPattern
(isDefined(variables) ?
"using" "{" [
variables
] "}"
)
(isDefined(outPattern) ? outPattern)
(isDefined(actionBlock) ? actionBlock)
] "}"
;
template LazyMatchedRule context addToContext
: (isUnique ? "unique") "lazy" (isAbstract ? "abstract") (isRefining ? "refining") "rule" name (isDefined(superRule) ? "extends" superRule{refersTo = name, importContext}) "{" [
inPattern
(isDefined(variables) ?
"using" "{" [
variables
] "}"
)
(isDefined(outPattern) ? outPattern)
(isDefined(actionBlock) ? actionBlock)
] "}"
;
template RuleVariableDeclaration addToContext
: varName ":" type "=" initExpression ";"
;
template CalledRule (disambiguate = "(\"entrypoint\" | \"endpoint\")? \"rule\" NAME LPAREN") context addToContext
: (isEntrypoint ? "entrypoint")
(isEndpoint ? "endpoint")
"rule" name "(" parameters{separator = ","} ")" "{" [
(isDefined(variables) ?
"using" "{" [
variables
] "}"
)
(isDefined(outPattern) ? outPattern)
(isDefined(actionBlock) ? actionBlock)
] "}"
;
-- @end Rules
-- @begin InPattern
template InPattern
: "from" [
elements{separator = ","}
(isDefined(filter) ? "(" [ filter ] ")")
]
;
template InPatternElement abstract addToContext;
template SimpleInPatternElement
: varName ":" type
(isDefined(models) ? "in" models{separator = ",", refersTo = name, lookIn = #all})
;
-- @end InPattern
-- @begin OutPattern
template OutPattern
: "to" [ elements{separator = ","} ] {endNL = false}
;
template OutPatternElement abstract addToContext;
template SimpleOutPatternElement
: varName ":" type
(isDefined(model) ? "in" model{separator = ",", refersTo = name, lookIn = #all})
(isDefined(sourceElement) ? "mapsTo" sourceElement{refersTo = varName})
(isDefined(reverseBindings) ? "->" "(" reverseBindings{separator = ","} ")")
(isDefined(bindings) ?
<space> "(" [
bindings{separator = ","}
] ")"
)
;
template ForEachOutPatternElement context
: varName ":" "distinct" type "foreach" "(" iterator "in" collection ")"
(isDefined(sourceElement) ? "mapsTo" sourceElement{refersTo = varName})
(isDefined(bindings) ?
<space> "(" [
bindings{separator = ","}
] ")"
)
;
template Binding
: propertyName{as = identifierOrKeyword}
(isAssignment ? "<:=" : "<-") 'value'
;
-- @end OutPattern
template ActionBlock
: "do" "{" [
statements
] "}"
;
-- @begin Statements
template Statement abstract;
template BindingStat
: 'source' (isAssignment ? "<:=" : "<-") 'value' ";"
;
template ExpressionStat (disambiguate = "oclExpression SEMI")
: expression ";"
;
template IfStat(disambiguate = "\"if\" LPAREN oclExpression RPAREN (LCURLY | statement)")
: "if" "(" condition ")"
(one(thenStatements) ?
[ thenStatements ]
:
"{" [
thenStatements
] "}"
)
(isDefined(elseStatements) ?
"else"
(one(elseStatements) ?
[ elseStatements ]
:
"{" [
elseStatements
] "}"
)
)
;
template ForStat context
: "for" "(" iterator "in" collection ")" "{" [
statements
] "}"
;
-- @end Statements
-- @begin Models
template OclModel
: name ":" metamodel{refersTo = name, lookIn = #all, autoCreate = ifmissing}
;
template OclModelElement
: model{refersTo = name, lookIn = #all, autoCreate = ifmissing} "!" name
;
-- @end Models
-- @begin OCL
template OclExpression abstract operatored;
-- @begin operatored
operatorTemplate IteratorExp(operators = opRarrow, source = 'source', disambiguate = "NAME LPAREN NAME (PIPE | ((COMA NAME)+ PIPE))") context
: name "(" iterators{separator = ","} "|" [
body
] ")"
;
operatorTemplate IterateExp(operators = opRarrow, source = 'source') context
: "iterate" "(" iterators{separator = ","} ";" result "|" [
body
] ")"
;
operatorTemplate CollectionOperationCallExp(operators = opRarrow, source = 'source')
-- operationName cannot be {as = identifierOrKeyword} because of ->iterate
: operationName "(" arguments{separator = ","} ")"
;
operatorTemplate OperationCallExp(operators = opPoint, source = 'source', disambiguate = "NAME LPAREN", disambiguateV3 = "NAME LPAREN")
: operationName{as = identifierOrKeyword} "(" arguments{separator = ","} ")"
;
operatorTemplate NavigationOrAttributeCallExp(operators = opPoint, source = 'source')
: name{as = identifierOrKeyword}
;
operatorTemplate OperatorCallExp(operators =
opNot opMinus1
opStar opSlash opDiv opMod
opPlus opMinus2
opEq opGt opLt opGe opLe opNe
opAnd opOr opXor opImplies
, source = 'source', storeOpTo = operationName, storeRightTo = arguments);
-- @end operatored
template Iterator addToContext
: varName
;
-- @begin values
template OclUndefinedExp
: "OclUndefined"
;
template PrimitiveExp abstract;
template NumericExp abstract;
template BooleanExp
: (booleanSymbol ? "true" : "false")
;
template IntegerExp
: integerSymbol
;
template RealExp
: realSymbol
;
template StringExp
: stringSymbol{as = stringSymbol}
;
-- @end values
template IfExp
: "if" condition "then" [
thenExpression
] "else" [
elseExpression
] "endif"
;
template VariableExp(disambiguate = "NAME ~(EXCL)")
: referredVariable{refersTo = varName, autoCreate = ifmissing}
;
template SuperExp
: "super"
;
template LetExp context nonPrimary
: "let" variable "in"
[ in_ ] {indentIncr = 0, endNL = false}
;
template VariableDeclaration addToContext
: varName ":" type "=" initExpression
;
template EnumLiteralExp
: "#" name
;
-- @begin CollectionExps
template CollectionExp abstract;
template BagExp
: "Bag" "{" elements{separator = ","} "}"
;
template SetExp
: "Set" "{" elements{separator = ","} "}"
;
template OrderedSetExp
: "OrderedSet" "{" elements{separator = ","} "}"
;
template SequenceExp
: "Sequence" "{" elements{separator = ","} "}"
;
-- @end CollectionExps
template MapExp
: "Map" "{" elements{separator = ","} "}"
;
template MapElement
: "(" key "," 'value' ")"
;
template TupleExp
: "Tuple" "{" tuplePart{separator= ","} "}"
;
template TuplePart
: varName{as = identifierOrKeyword} (isDefined(type) ? ":" type) "=" initExpression
;
-- @begin OclType
template OclType abstract
: "OclType"
;
template OclAnyType
: "OclAny"
;
template TupleType
: "TupleType" "(" attributes{separator = ","} ")"
;
template TupleTypeAttribute
: name ":" type
;
template MapType
: "Map" "(" keyType "," valueType ")"
;
template Primitive abstract;
template NumericType abstract;
template IntegerType
: "Integer"
;
template RealType
: "Real"
;
template BooleanType
: "Boolean"
;
template StringType
: "String"
;
template CollectionType abstract
: "Collection" "(" elementType ")"
;
template BagType
: "Bag" "(" elementType ")"
;
template SetType
: "Set" "(" elementType ")"
;
template OrderedSetType
: "OrderedSet" "(" elementType ")"
;
template SequenceType
: "Sequence" "(" elementType ")"
;
-- @end OclTypes
-- @end OCL
symbols {
lsquare = "[";
rsquare = "]" : rightSpace;
excl = "!";
coma = "," : leftNone, rightSpace;
lparen = "(";
rparen = ")" : leftNone, rightSpace;
lcurly = "{" : leftSpace;
rcurly = "}" : leftNone, rightSpace;
semi = ";" : leftNone, rightSpace;
colon = ":" : leftSpace, rightSpace; -- except after def where it is leftNone, rightSpace
pipe = "|" : leftSpace, rightSpace;
sharp = "#" : leftSpace;
qmark = "?";
arobas = "@" : rightNone;
-- operator symbols
point = "." : leftNone;
rarrow = "->" : leftNone;
minus = "-" : leftSpace, rightSpace;
star = "*" : leftSpace, rightSpace;
slash = "/" : leftSpace, rightSpace;
plus = "+" : leftSpace, rightSpace;
eq = "=" : leftSpace, rightSpace;
gt = ">" : leftSpace, rightSpace;
lt = "<" : leftSpace, rightSpace;
ge = ">=" : leftSpace, rightSpace;
le = "<=" : leftSpace, rightSpace;
ne = "<>" : leftSpace, rightSpace;
larrow = "<-" : leftSpace, rightSpace;
assignarrow = "<:=" : leftSpace, rightSpace;
}
operators {
priority 0 { -- 0 is highest
opPoint = point, 2;
opRarrow = rarrow, 2;
}
priority 1 {
opNot = "not", 1; -- no corresponding symbol => symbol is the keyword defined by the quoted string (which is also the name)
opMinus1 = minus, 1;
}
priority 2 {
opStar = star, 2;
opSlash = slash, 2;
opDiv = "div", 2;
opMod = "mod", 2;
}
priority 3 {
opPlus = plus, 2;
opMinus2 = minus, 2;
}
priority 4 {
opEq = eq, 2;
opGt = gt, 2;
opLt = lt, 2;
opGe = ge, 2;
opLe = le, 2;
opNe = ne, 2;
}
priority 5 {
opAnd = "and", 2;
opOr = "or", 2;
opXor = "xor", 2;
opImplies = "implies", 2;
}
}
token COMMENT : endOfLine(start = "--");
token STRING : multiLine(start = "\'", end = "\'", esc = "\\");
lexer = "
%options testLiterals = false;
NL
: ( '\\r' '\\n'
| '\\n' '\\r' //Improbable
| '\\r'
| '\\n'
)
{newline();}
;
WS
: ( ' '
| '\\t'
)
;
%protected
DIGIT
: '0'..'9'
;
%protected
ALPHA
: 'a'..'z'
| 'A'..'Z'
| '_'
//For Unicode compatibility (from 0000 to 00ff)
| '\\u00C0' .. '\\u00D6'
| '\\u00D8' .. '\\u00F6'
| '\\u00F8' .. '\\u00FF'
;
%protected
SNAME
%v2 options {
%v2 testLiterals = true;
%v2 }
%v2 : (ALPHA) (ALPHA | DIGIT | {LA(2) == ':'}?':' ':')*
//TODO:%v3 : (ALPHA) (ALPHA | DIGIT | {input.LA(2) == ':'}?':' ':')*
%v3 : (ALPHA) (ALPHA | DIGIT)*
;
NAME
: (
%v3 SNAME
%v2 s:SNAME {if(s.getType() != SNAME) $setType(s.getType());}
| '\"'!
( ESC
| '\\n' {newline();}
| ~('\\\\'|'\\\"'|'\\n')
)*
'\"'!
%v3 {setText(ei.unescapeString(getText(), 1));}
)
;
INT
: (DIGIT)+
// cannot accept DIGIT '.' because it would conflict with Navigation
%v2 (('.' DIGIT)=> '.' (DIGIT)+ {$setType(FLOAT);})?
%v3 (|{ ((input.LA(2) >= '0') && (input.LA(2) <= '9')) }? => '.' DIGIT+ {$type = FLOAT;})
;
%v3 fragment FLOAT:;
%protected
ESC
: '\\\\'!
( 'n' %v2{%setText(\"\\n\");}
| 'r' %v2{%setText(\"\\r\");}
| 't' %v2{%setText(\"\\t\");}
| 'b' %v2{%setText(\"\\b\");}
| 'f' %v2{%setText(\"\\f\");}
| '\"' %v2{%setText(\"\\\"\");}
| '\\'' %v2{%setText(\"\\'\");}
| '\\\\' %v2{%setText(\"\\\\\");}
| (
('0'..'3')
(
%v2 options {
%v2 warnWhenFollowAmbig = false;
%v2 }
: ('0'..'7')
(
%v2 options {
%v2 warnWhenFollowAmbig = false;
%v2 }
: '0'..'7'
)?
)?
| ('4'..'7')
(
%v2 options {
%v2 warnWhenFollowAmbig = false;
%v2 }
: ('0'..'7')
)?
)
{
%v2 String s = %getText;
%v2 int i;
%v2 int ret = 0;
%v2 String ans;
%v2 for (i=0; i<s.length(); ++i)
%v2 ret = ret*8 + s.charAt(i) - '0';
%v2 ans = String.valueOf((char) ret);
%v2 %setText(ans);
}
)
;
";
}