-- @authors Frédéric Jouault -- @date 2005/04/07 -- @description This TCS model defines the syntax of the Program language. syntax Program { primitiveTemplate identifier for String default using NAME: value = "%token%"; primitiveTemplate stringSymbol for String using STRING: value = "%token%", 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%)"; template Program main context : "program" name "{" [ variables procedures monitors ] {nbNL = 2} "}" ; template Monitor context : "monitor" name "{" [ variables procedures ] {nbNL = 2} "}" ; template VariableDeclaration addToContext : "var" name ":" type{refersTo = name, autoCreate = ifmissing, lookIn = #all} (isDefined(initialValue) ? ":=" initialValue) ";" ; template Procedure context : "procedure" name "(" parameters{separator = ","} ")" "{" [ variables statements ] "}" ; template Parameter addToContext : -- simple version direction -- more complex version -- (direction = #in ? "in" : -- (direction = #out ? "out")) name ":" type{refersTo = name, autoCreate = ifmissing, lookIn = #all} ; enumerationTemplate Direction : #in = "in", #out = "out" ; -- Types template Type : name ; -- End Types -- Expressions template Expression abstract operatored; template VariableExp : declaration{refersTo = name} ; template LiteralExp abstract; template BooleanExp : (symbol ? "true" : "false") ; template IntegerExp : symbol ; operatorTemplate ProcedureCallExp(operators = opPoint, source = 'source') : name "(" arguments{separator = ","} ")" ; operatorTemplate AttributeCallExp(operators = opPoint, source = 'source') : name ; operatorTemplate OperatorCallExp(operators = opAnd opOr opPlus opMinus2 opMinus1 opStar opDiv opSlash opMod opLt opLe opEq opNe opGe opGt, source = 'source', storeOpTo = name, storeRightTo = 'right'); -- End Expressions -- Statements template Statement abstract; template AssignmentStat : target ":=" 'value' ";" ; template ConditionalStat : "if" condition "then" "{" [ thenStats ] "}" (isDefined(elseStats) ? "else" "{" [ elseStats ] "}") ; template WhileStat : "while" condition "do" "{" [ doStats ] "}" ; template ExpressionStat : expression ";" ; -- End Statements symbols { lsquare = "["; rsquare = "]"; excl = "!"; coma = ","; lparen = "("; rparen = ")" : rightSpace; lcurly = "{" : leftSpace; rcurly = "}" : rightSpace; semi = ";" : leftNone; colon = ":" : leftSpace, rightSpace; pipe = "|"; sharp = "#"; qmark = "?"; -- operator symbols point = "." : leftNone; rarrow = "->"; 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; assign = ":=" : leftSpace, rightSpace; } operators { priority 0 { opPoint = point, 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; } } 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));} ) ; INT : (DIGIT)+ %v2 (('.' DIGIT)=> '.' (DIGIT)+ {$setType(FLOAT);})? ; %v3 FLOAT : DIGIT+ (('.' DIGIT)=>'.' DIGIT+)? ; // cannot accept DIGIT '.' because it would conflict with Navigation %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