-- @name FPath
-- @version 1.0
-- @authors Frédéric Jouault
-- @date 20080124
-- @description Concrete syntax of the FPath Fractal navigation language.
-- The different sections of a TCS model have been enclosed between BEGIN and END
-- comments below. Additional information is provided below each BEGIN comment.
-- The main sections of interest are "Class templates", and
-- "Operator table" (the latter only for DSLs using operators).
syntax FPath {
-- BEGIN Primitive templates
-- Specifies representation of primitive types.
-- Only needs modification when default lexer is not satisfactory.
-- Generally modified along with the lexer.
primitiveTemplate identifier for String default using NAME:
value = "%token%";
primitiveTemplate stringSymbol for String using STRING:
value = "%token%",
serializer="'\'' + %value%.toCString() + '\''";
primitiveTemplate floatSymbol for Double default using FLOAT:
value = "Double.valueOf(%token%)";
-- END Primitive templates
-- BEGIN Class templates
-- Specifies representation of classes.
-- This is the main section to work on.
template Expression main abstract operatored;
template ContextExp
: "."
;
template VariableExp
: "$" name
;
template FunctionCallExp
: name "(" arguments{separator = ","} ")"
;
template NumberExp
: 'value'
;
template StringExp
: 'value'{as = stringSymbol}
;
operatorTemplate PathExp(operators = opSlash, source = initialNodeSet)
: steps{separator = "/"}
;
operatorTemplate BinaryOperatorExp(operators =
opMul opDiv
opPlus opMinus2
opLt opGt opLe opGe opEq opNe
opAnd opOr
, source = 'left', storeOpTo = operator, storeRightTo = 'right'
);
operatorTemplate UnaryOperatorExp(operators =
opNot opMinus1
, source = operand, storeOpTo = operator
);
template Step
: axis "::" test (isDefined(predicates) ? "[" predicates{separator = "]" "["} "]")
;
template Test abstract;
template WildcardTest
: "*"
;
template NameTest
: name
;
enumerationTemplate Axis
: #component = "component",
#'internal-interface' = "internal-interface",
#interface = "interface",
#attribute = "attribute",
#binding = "binding",
#child = "child",
#parent = "parent",
#descendant = "descendant",
#ancestor = "ancestor",
#sibling = "sibling",
#'descendant-or-self' = "descendant-or-self",
#'ancestor-or-self' = "ancestor-or-self",
#'sibling-or-self' = "sibling-or-self"
;
-- END Class templates
-- BEGIN Special symbols
-- Possible modifications:
-- - Addition of new symbols.
-- - Modification of spaces information.
-- - Removal of unused symbols so that using these symbols results in lexical
-- error rather than parsing error.
symbols {
lsquare = "[";
rsquare = "]" : rightSpace;
excl = "!";
coma = "," : leftNone, rightSpace;
lparen = "(";
rparen = ")" : leftNone, rightSpace;
lcurly = "{" : leftSpace;
rcurly = "}" : leftNone, rightSpace;
semi = ";" : leftNone, rightSpace;
colon = ":" : leftSpace, rightSpace;
coloncolon = "::" : leftNone, rightNone;
pipe = "|" : leftSpace, rightSpace;
sharp = "#" : leftSpace;
qmark = "?";
-- operator symbols
point = "." : leftNone;
rarrow = "->" : leftNone;
minus = "-" : leftSpace, rightSpace;
star = "*" : leftSpace, rightSpace;
slash = "/" : leftSpace, rightSpace;
plus = "+" : leftSpace, rightSpace;
eq = "=" : leftSpace, rightSpace;
eqeq = "==" : leftSpace, rightSpace;
gt = ">" : leftSpace, rightSpace;
lt = "<" : leftSpace, rightSpace;
ge = ">=" : leftSpace, rightSpace;
le = "<=" : leftSpace, rightSpace;
ne = "<>" : leftSpace, rightSpace;
larrow = "<-" : leftSpace, rightSpace;
}
-- END Special symbols
-- BEGIN Operator table
-- Defines all operators with their priority, arity, and associativity.
-- All defined operators must be used in operator templates.
operators {
priority 0 { -- highest priority
opSlash = slash, 2;
}
priority 1 {
opNot = "not", 1;
opMinus1 = minus, 1;
}
priority 2 {
opMul = star, 2;
opDiv = "div", 2;
}
priority 3 {
opPlus = plus, 2;
opMinus2 = minus, 2;
}
priority 4 {
opLt = lt, 2;
opGt = gt, 2;
opLe = le, 2;
opGe = ge, 2;
opEq = eqeq, 2;
opNe = ne, 2;
}
priority 5 {
opAnd = "and", 2;
opOr = "or", 2;
}
}
-- END Operator table
-- BEGIN Lexer
-- Specifies the lexical entities.
-- Only needs modification when default lexer is not satisfactory.
-- Generally modified along with Primitive templates.
token COMMENT : endOfLine(start = "--");
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 }
: (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));}
)
;
%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
: '\\''!
( ESC
| '\\n' {newline();}
| ~('\\\\'|'\\''|'\\n')
)*
'\\''!
%v3 {setText(ei.unescapeString(getText(), 1));}
;
";
-- END Lexer
}