blob: b7437ad23def8480ce3a006bea0d9fb01519c13e [file] [log] [blame]
-- @authors Frédéric Jouault
-- @date 2007/07/25
-- @description This TCS model defines the syntax of the ACG language.
syntax ACG {
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%)";
template ACG main
: "acg" metamodel "startsWith" startsWith "{" [
elements
] "}"
;
template ACGElement abstract;
template Function
: "function" context "::" name
"(" (isDefined(parameters) ? parameters{forcedLower = 1, separator = ","} ) ")" "="
body ";"
;
template Attribute
: "attribute" context "::" name "="
body ";"
;
template Parameter addToContext
: name
;
-- @begin Nodes
template Node abstract;
template ASMNode context
: "asm" element "name" name
-- NO mode or guard for ASMNodes:
-- (isDefined(mode) ?
-- "mode" mode
-- )
-- (isDefined(guard) ? "|" guard)
"{" [
statements
] "}"
;
template CodeNode context
: "code" element
(isDefined(mode) ?
"mode" mode
)
(isDefined(guard) ? "|" guard)
"{" [
statements
] "}"
;
template SimpleNode context
: element
(isDefined(mode) ?
"mode" mode
)
(isDefined(guard) ? "|" guard)
"{" [
statements
] "}"
;
-- @end Nodes
-- @begin Statements
template Statement abstract;
-- @begin CompoundStats
template CompoundStat(disambiguate = "(\"if\" LPAREN expression RPAREN LCURLY) | \"foreach\" | \"variable\" | \"operation\" | LSQUARE | \"let\" | \"analyze\"") abstract context;
template ForEachStat context
: "foreach" "(" iterator "in" collection ")" "{" [
statements
] "}"
;
template OnceStat
: "[" [
statements
] "]"
;
template VariableStat
: "variable" definition "named" name "{" [
statements
] "}"
;
template OperationStat context
: "operation" "context" context "name" name "{" [
statements
] "}"
;
template ConditionalStat
: "if" "(" condition ")" "{" [
statements
] "}"
(isDefined(elseStatements) ?
"else" "{" [
elseStatements
] "}"
)
;
template LetStat context
: "let" variable "=" value "{" [
statements
] "}"
;
template AnalyzeStat
: "analyze" target
(isDefined(mode) ?
"mode" mode
)
(isDefined(statements) ?
"{" [
statements
] "}"
)
;
-- @end CompoundStats
template ReportStat
: "report" severity message
;
enumerationTemplate Severity
: #critic = "critic",
#error = "error",
#warning = "warning"
;
template FieldStat
: "field" name ":" type
;
template ParamStat
: "param" name ":" type
;
-- @begin EmitStats
template EmitStat abstract;
template LabelStat addToContext
: name (isDefined(id) ? "(" id ")") ":"
;
template NewStat
: "new"
;
template NewinStat
: "newin"
;
template DeleteStat
: "delete"
;
template DupStat
: "dup"
;
template DupX1Stat
: "dup_x1"
;
template PopStat
: "pop"
;
template SwapStat
: "swap"
;
template IterateStat
: "iterate"
;
template EndIterateStat
: "enditerate"
;
template GetAsmStat
: "getasm"
;
template FindMEStat
: "findme"
;
template PushTStat
: "pusht"
;
template PushFStat
: "pushf"
;
-- @begin EmitWithOperandStats
template EmitWithOperandStat abstract;
template PushStat
: "push" operand
;
template PushIStat
: "pushi" operand
;
template PushDStat
: "pushd" operand
;
template LoadStat
: "load" operand
;
template StoreStat
: "store" operand
;
template CallStat
: "call" operand
;
template PCallStat
: "pcall" operand
;
template SuperCallStat
: "supercall" operand
;
template GetStat
: "get" operand
;
template SetStat
: "set" operand
;
-- @end EmitWithOperandStats
-- @begin EmitWithLabelRefStats
template EmitWithLabelRefStat abstract;
template GotoStat
: "goto" label{refersTo = name}
;
template IfStat
: "if" label{refersTo = name}
;
-- @end EmitWithLabelRefStats
-- @end EmitStats
-- @end Statements
template VariableDecl addToContext
: name
;
-- @begin Expressions
template Expression abstract operatored;
template VariableExp
: variable{refersTo = name}
;
template SelfExp
: "self"
;
template LastExp
: "last"
;
template IfExp
: "if" condition "then" thenExp "else" elseExp "endif"
;
operatorTemplate IsAExp(operators = opIsa, source = 'source')
: type
;
template LetExp context nonPrimary
: "let" variable "=" value "in" in
;
-- @begin PropertyCallExps
operatorTemplate NavigationExp(operators = opPoint, source = 'source')
: name{as = identifierOrKeyword}
;
operatorTemplate IteratorExp(operators = opRarrow, source = 'source') context
: name{as = identifierOrKeyword} "(" iterator "|" body ")"
;
operatorTemplate OperationCallExp(operators = opPoint, source = 'source')
: name {as = identifierOrKeyword} "(" arguments{separator = ","} ")"
;
operatorTemplate OperatorCallExp(operators =
opNot opMinus1
opStar opSlash opDiv opMod
opPlus opMinus2
opEq opGt opLt opGe opLe opNe
opAnd opOr opXor opImplies,
source = 'source', storeOpTo = name, storeRightTo = arguments);
-- @end PropertyCallExps
-- @begin LiteralExps
template LiteralExp abstract;
template OclUndefinedExp
: "OclUndefined"
;
-- @begin CollectionExps
template CollectionExp abstract;
template SequenceExp
: "Sequence" "{" elements{separator = ","} "}"
;
-- @end CollectionExps
-- @begin Primitive LiteralExps
template BooleanExp
: (value ? "true" : "false")
;
template IntegerExp
: value
;
template StringExp
: value{as = stringSymbol}
;
-- @end Primitive LiteralExps
-- @end LiteralExps
-- @end Expressions
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 = "?";
coloncolon = "::" : leftNone, 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;
}
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;
opIsa = "isa", 2;
}
priority 5 {
opAnd = "and", 2;
opOr = "or", 2;
opXor = "xor", 2;
opImplies = "implies", 2;
}
}
token COMMENT : endOfLine(start = "--");
lexer = "
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 }
: (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)+
%v2 (('.' DIGIT)=> '.' (DIGIT)+ {$setType(FLOAT);})?
;
%v3 FLOAT : DIGIT+ '.' DIGIT* ;
%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);
}
)
;
STRING @init {}
: (('\\'' (options {greedy = false;} : (('\\\\' ~ '\\n')| '\\n'| ~('\\\\'| '\\n')))* '\\''))
{
}
;
";
}