]> gerrit.simantics Code Review - simantics/interop.git/blob - org.simantics.express/src/org/simantics/express/parser/ExpressParser.jj
Moved /interoperability/branches/dev/* to /interoperability/trunk
[simantics/interop.git] / org.simantics.express / src / org / simantics / express / parser / ExpressParser.jj
1 options {\r
2   JDK_VERSION = "1.6";\r
3   STATIC = false;\r
4   IGNORE_CASE = true;\r
5 }\r
6 \r
7 PARSER_BEGIN(ExpressParser)\r
8 package org.simantics.express.parser; \r
9 import org.simantics.express.ast.types.*;\r
10 import org.simantics.express.ast.expressions.*;\r
11 import java.util.List;\r
12 import java.util.ArrayList;\r
13 \r
14 public class ExpressParser {\r
15 }\r
16 PARSER_END(ExpressParser)\r
17 \r
18 /* Lexer */\r
19 \r
20 SKIP:\r
21 { <WHITESPACE: " " | "\n" | "\r" | "\t" > \r
22 | <COMMENT1: "(*" (~["*"] | "*" ~[")"])* "*)" >  \r
23 | <COMMENT2: "--" (~["\n"])* >\r
24 }\r
25 \r
26 TOKEN:\r
27 { ";" | "(" | ")" | "\\" | "?" | "[" | "]"\r
28 | "{" | "}" | "|" | "&" | ":" | ":=" | ":=:"\r
29 | ":<>:" | "," | "." | "=" | "<" | ">"\r
30 | "<=" | ">=" | "/" | "+" | "-" | "*" | "@"\r
31 | "<*" | "<>" | "**" | "||" \r
32 | <ENTITY:"ENTITY"> \r
33 | <END_ENTITY:"END_ENTITY">\r
34 | <SCHEMA:"SCHEMA"> \r
35 | <END_SCHEMA:"END_SCHEMA">\r
36 | <CONSTANT:"CONSTANT"> \r
37 | <END_CONSTANT:"END_CONSTANT">\r
38 | <FUNCTION:"FUNCTION"> \r
39 | <END_FUNCTION:"END_FUNCTION">\r
40 | <PROCEDURE:"PROCEDURE"> \r
41 | <END_PROCEDURE:"END_PROCEDURE">\r
42 | <RULE:"RULE"> \r
43 | <END_RULE:"END_RULE">\r
44 | <TYPE:"TYPE"> \r
45 | <END_TYPE:"END_TYPE">\r
46 | <SUBTYPE_CONSTRAINT:"SUBTYPE_CONSTRAINT"> \r
47 | <END_SUBTYPE_CONSTRAINT:"END_SUBTYPE_CONSTRAINT">\r
48 | <LOCAL:"LOCAL"> \r
49 | <END_LOCAL:"END_LOCAL">\r
50 \r
51 | <ABSTRACT:"ABSTRACT"> \r
52 | <EXTENSIBLE:"EXTENSIBLE">\r
53 | <GENERIC_ENTITY:"GENERIC_ENTITY">\r
54 | <BASED_ON:"BASED_ON">\r
55 | <WITH:"WITH">\r
56 | <SUBTYPE:"SUBTYPE"> \r
57 | <SUPERTYPE:"SUPERTYPE"> \r
58 | <OF:"OF">\r
59 | <ONEOF:"ONEOF">\r
60 | <ANDOR:"ANDOR"> \r
61 | <AND:"AND"> \r
62 | <SELF:"SELF">\r
63 | <USE:"USE">\r
64 | <REFERENCE:"REFERENCE">\r
65 | <FROM:"FROM">\r
66 | <FOR:"FOR">\r
67 | <DERIVE:"DERIVE">\r
68 | <INVERSE:"INVERSE">\r
69 | <OPTIONAL:"OPTIONAL">\r
70 | <FIXED:"FIXED">\r
71 | <UNIQUE:"UNIQUE">\r
72 | <WHERE:"WHERE">\r
73 | <LIKE:"LIKE">\r
74 | <IN:"IN">\r
75 | <OR:"OR">\r
76 | <XOR:"XOR">\r
77 | <MOD:"MOD">\r
78 | <DIV:"DIV">\r
79 | <QUERY:"QUERY">\r
80 | <NOT:"NOT">\r
81 | <AS:"AS">\r
82 | <TRUE:"TRUE">\r
83 | <FALSE:"FALSE">\r
84 | <RENAMED:"RENAMED">\r
85 \r
86 | <STRING_:"STRING">\r
87 | <INTEGER:"INTEGER">\r
88 | <REAL:"REAL">\r
89 | <NUMBER:"NUMBER">\r
90 | <BOOLEAN:"BOOLEAN">\r
91 | <LOGICAL:"LOGICAL">\r
92 | <BINARY:"BINARY">\r
93 | <BAG:"BAG">\r
94 | <ARRAY:"ARRAY">\r
95 | <LIST:"LIST">\r
96 | <SET:"SET">\r
97 | <SELECT:"SELECT">\r
98 | <ENUMERATION:"ENUMERATION">\r
99 | <GENERIC:"GENERIC">\r
100 | <AGGREGATE:"AGGREGATE">\r
101 \r
102 | <ALIAS: "ALIAS">\r
103 | <RETURN: "RETURN">\r
104 | <IF: "IF">\r
105 | <END_IF: "END_IF">\r
106 | <THEN: "THEN">\r
107 | <ELSE: "ELSE">\r
108 | <REPEAT: "REPEAT">\r
109 | <END_REPEAT: "END_REPEAT">\r
110 | <TO: "TO">\r
111 | <BY: "BY">\r
112 | <WHILE: "WHILE">\r
113 | <UNTIL: "UNTIL">\r
114 | <CASE: "CASE">\r
115 | <END_CASE: "END_CASE">\r
116 | <BEGIN: "BEGIN">\r
117 | <END: "END">\r
118 | <ESCAPE: "ESCAPE">\r
119 | <SKIP_: "SKIP">\r
120 | <VAR: "VAR">\r
121 \r
122 | <STRING: "'" (~["'"])* "'">\r
123 | <IDENT: ["a"-"z","A"-"Z"] (["a"-"z","A"-"Z","_","0"-"9"])* >\r
124 | <INT: (["0"-"9"])+ >\r
125 | <FLOAT: <INT> "." (<INT>)? (("e"|"E") ("+"|"-")?  <INT>)? >\r
126 }\r
127 \r
128 /* Parser */\r
129 \r
130 void document() : {}\r
131 { (schema())* <EOF>\r
132 }\r
133 \r
134 void schema() : {}\r
135 { <SCHEMA> <IDENT> ";" \r
136         (interface_())*\r
137         (constDecl())?\r
138         (decl())*\r
139   <END_SCHEMA> ";"\r
140 }\r
141 \r
142 void interface_() : {}\r
143 { <USE> <FROM> <IDENT> ( "(" references() ")" )? ";"\r
144 | <REFERENCE> <FROM> <IDENT> ( "(" references() ")" )? ";"\r
145 }\r
146 \r
147 void references() : {}\r
148 { reference() ("," reference())* \r
149 }\r
150 \r
151 void reference() : {}\r
152 { <IDENT> (<AS> <IDENT>)? \r
153 }\r
154 \r
155 void constDecl() : {}\r
156 { <CONSTANT> (<IDENT> ":" typeB() ":=" exp() ";")+ <END_CONSTANT> ";"\r
157 }\r
158 \r
159 void decl() : {}\r
160 { ruleDecl()\r
161 | decl0()\r
162 }\r
163 \r
164 void ruleDecl() : {}\r
165 { <RULE> <IDENT> <FOR> "(" idents() ")" ";" \r
166         localDecls()\r
167         (statement())*\r
168         where()\r
169   <END_RULE> ";"\r
170 }\r
171 \r
172 void decl0() : {}\r
173 { entityDecl()\r
174 | functionDecl()\r
175 | procedureDecl()\r
176 | typeDecl()\r
177 | subtypeConstraintDecl()\r
178 }\r
179 \r
180 void entityDecl() : {}\r
181 { <ENTITY> <IDENT> (supertype())? (subtype())? ";"\r
182          (attributes() ":" (<OPTIONAL>)? typeB() ";")*\r
183          (<DERIVE> (attribute() ":" typeB() ":=" exp() ";")+ )?\r
184          (<INVERSE> (attribute() ":" typeI() <FOR> attribute() ";")+ )?\r
185          (<UNIQUE> ( ( LOOKAHEAD(2) <IDENT> ":")? attributes() ";")+ )?\r
186          (where())?\r
187   <END_ENTITY> ";"\r
188 }\r
189 \r
190 void localDecls() : {}\r
191 { (decl0())*\r
192   (constDecl())?\r
193   (<LOCAL> ( idents() ":" typeP() (":=" exp())* ";")+ <END_LOCAL> ";")?\r
194 }\r
195 \r
196 void functionDecl() : {}\r
197 { <FUNCTION> <IDENT> ("(" parameter() (";" parameter())* ")")? ":" typeP() ";" \r
198         localDecls()\r
199         (statement())+\r
200   <END_FUNCTION> ";"\r
201 }\r
202 \r
203 void procedureDecl() : {}\r
204 { <PROCEDURE> <IDENT> ("(" parameterP() (";" parameterP())* ")")? ";" \r
205     localDecls()\r
206     (statement())+\r
207   <END_PROCEDURE> ";"\r
208 }\r
209 \r
210 void typeDecl() : {}\r
211 { <TYPE> <IDENT> "=" typeU() ";" (where())? <END_TYPE> ";"\r
212 }\r
213 \r
214 void subtypeConstraintDecl() : {}\r
215 { <SUBTYPE_CONSTRAINT> <IDENT> <FOR> <IDENT> ";"\r
216         (<ABSTRACT> <SUPERTYPE> ";")?\r
217         (supertypeExpression() ";")?\r
218   <END_SUBTYPE_CONSTRAINT> ";"\r
219 }\r
220 \r
221 void where() : {}\r
222 { <WHERE> ( ( LOOKAHEAD(2) <IDENT> ":")? exp() ";")+\r
223 }\r
224 \r
225 void parameter() : {}\r
226 { idents() ":" typeP()\r
227 }\r
228 \r
229 void parameterP() : {}\r
230 { parameter()\r
231 | <VAR> parameterP()\r
232 }\r
233 \r
234 void supertype() : {}\r
235 { <SUPERTYPE> <OF> "(" supertypeExpression() ")"\r
236 | <ABSTRACT> <SUPERTYPE> (<OF> "(" supertypeExpression() ")")?\r
237 }\r
238 \r
239 void supertypeExpression() : {}\r
240 { supertypeExpression2() (<ANDOR> supertypeExpression2())*\r
241 }\r
242 \r
243 void supertypeExpression2() : {}\r
244 { supertypeExpression3() (<AND> supertypeExpression3())*\r
245 }\r
246 \r
247 void subtype() : {}\r
248 { <SUBTYPE> <OF> "(" idents() ")"\r
249 }\r
250 \r
251 void supertypeExpression3() : {}\r
252 { <IDENT>\r
253 | <ONEOF> "(" supertypeExpression() ("," supertypeExpression())* ")"\r
254 | "(" supertypeExpression() ")"\r
255 }\r
256 \r
257 void attribute() : {}\r
258 { <IDENT>\r
259 | <SELF> "\\" <IDENT> "." <IDENT> (<RENAMED> <IDENT>)?\r
260 }\r
261 \r
262 void attributes() : {}\r
263 { attribute() ("," attribute())*\r
264 }\r
265 \r
266 ExpType typeBI() : {}\r
267 { <BOOLEAN> { return ExpBoolean.INSTANCE; }\r
268 | <REAL> /* */ { return ExpReal.INSTANCE; }\r
269 | <NUMBER> { return ExpNumber.INSTANCE; }\r
270 | <BINARY> ( "(" exp1() ")")? ( <FIXED> )? { return ExpBinary.INSTANCE; }\r
271 | <LOGICAL> { return ExpLogical.INSTANCE; }\r
272 | <STRING_> ( "(" exp1() ")")? ( <FIXED> )? { return ExpString.INSTANCE; }\r
273 | <INTEGER> { return ExpInteger.INSTANCE; }\r
274 }\r
275 \r
276 ExpType typeB() : { ExpType type; }\r
277 { type=typeN() { return type; }\r
278 | type=typeBI() { return type; }\r
279 | type=typeA() { return type; }\r
280 }\r
281 \r
282 ExpType typeA() : { ExpType type; }\r
283 { <BAG> bound() <OF> type=typeB() { return new ExpBag(type); }\r
284 | <ARRAY> bound() <OF> (<OPTIONAL>)? (<UNIQUE>)? type=typeB() { return new ExpArray(type); }\r
285 | <LIST> bound() <OF> (<UNIQUE>)? type=typeB() { return new ExpList(type); }\r
286 | <SET> bound() <OF> type=typeB() { return new ExpSet(type); }\r
287 }\r
288 \r
289 ExpType typeI() : { ExpType type; }\r
290 { type=typeN() { return type; }\r
291 | <BAG> bound() <OF> type=typeN() { return new ExpBag(type); }\r
292 | <SET> bound() <OF> type=typeN() { return new ExpSet(type); }\r
293 }\r
294 \r
295 ExpType typeN() : { Token tt; }\r
296 { tt=<IDENT> { return new ExpTypeName(tt.image); }\r
297 }\r
298 \r
299 ExpType typeP() : { ExpType type; }\r
300 { type=typeBI() { return type; } \r
301 | type=typeN(){ return type; }\r
302 | <BAG> bound() <OF> type=typeP() { return new ExpBag(type); }\r
303 | <ARRAY> bound() <OF> (<OPTIONAL>)? (<UNIQUE>)? type=typeP() { return new ExpArray(type); }\r
304 | <LIST> bound() <OF> (<UNIQUE>)? type=typeP() { return new ExpList(type); }\r
305 | <SET> bound() <OF> type=typeP() { return new ExpSet(type); }\r
306 | <GENERIC> (":" <IDENT>)?  { return ExpGeneric.INSTANCE; }\r
307 | <GENERIC_ENTITY> { return ExpGenericEntity.INSTANCE; }\r
308 | <AGGREGATE> (":" <IDENT>)? <OF> type=typeP() { return new ExpAggregate(type); }\r
309 }\r
310 \r
311 ExpType typeU() : {}\r
312 { { ExpType type; } type=typeB() { return type; }\r
313 | LOOKAHEAD(3) (<EXTENSIBLE>)? (<GENERIC_ENTITY>)? <SELECT> \r
314     (<BASED_ON> <IDENT> (<WITH> "(" idents() ")")?\r
315     | "(" idents() ")"\r
316     )? { return new ExpSelect(); }\r
317 | LOOKAHEAD(3) (<EXTENSIBLE>)? (<GENERIC_ENTITY>)? <ENUMERATION> \r
318     (<BASED_ON> <IDENT> (<WITH> "(" idents() ")")?\r
319     | <OF> "(" idents() ")"\r
320     )? { return new ExpEnumeration(); }\r
321 }\r
322 \r
323 void bound() : {}\r
324 { ("[" exp1() ":" exp1() "]")?\r
325 }\r
326 \r
327 ExpExpression exp() : { ExpExpression exp; }\r
328 { exp=exp1() \r
329         ( {ExpExpression exp2; String op;} op=op0() exp2=exp1() \r
330             { exp = new ExpBinaryExpression(exp, op, exp2); } )? \r
331         { return exp; }\r
332 }\r
333 \r
334 String op0() : {}\r
335 { ">" { return ">"; }\r
336 | "<" { return "<"; } \r
337 | ">=" { return ">="; }\r
338 | "<=" { return "<="; }\r
339 | ":=:" { return ":=:"; } \r
340 | ":<>:" { return ":<>:"; }\r
341 | "=" { return "="; }\r
342 | "<>" { return "<>"; }\r
343 | <LIKE> { return "like"; } \r
344 | <IN> { return "in"; }\r
345 }\r
346 \r
347 ExpExpression exp1() : { ExpExpression exp; }\r
348 { exp=exp2() \r
349         ( {ExpExpression exp2; String op;} op=op1() exp2=exp2()\r
350            { exp = new ExpBinaryExpression(exp, op, exp2); }\r
351         )* \r
352         { return exp; }\r
353 }\r
354 \r
355 String op1() : {}\r
356 { <OR> { return "or"; }\r
357 | <XOR> { return "xor"; }\r
358 | "+" { return "+"; }\r
359 | "-" { return "-"; }\r
360 }\r
361 \r
362 ExpExpression exp2() : { ExpExpression exp; }\r
363 { exp=exp3() \r
364     ( {ExpExpression exp2; String op;} op=op2() exp2=exp3()\r
365        { exp = new ExpBinaryExpression(exp, op, exp2); }\r
366     )* \r
367     { return exp; }\r
368 }\r
369 \r
370 String op2() : {}\r
371 { <AND> { return "and"; }\r
372 | <MOD> { return "mod"; }\r
373 | <DIV> { return "div"; }\r
374 | "*" { return "*"; }\r
375 | "/" { return "/"; }\r
376 | "||" { return "||"; }\r
377 }\r
378 \r
379 ExpExpression exp3() : { ExpExpression exp; }\r
380 { exp=exp4() \r
381     ( {ExpExpression exp2;} "**" exp2=exp4()\r
382        { exp = new ExpBinaryExpression(exp, "**", exp2); }\r
383     )* \r
384     { return exp; }\r
385 }\r
386 \r
387 ExpExpression exp4() : { ExpExpression exp; }\r
388 { "[" (exp() (":" exp())? ("," exp() (":" exp())?)* )? "]"   { return null; }\r
389 | <QUERY> "(" <IDENT> "<*" exp1() "|" exp() ")" { return null; }\r
390 | "{" exp1() ("<" | "<=") exp1() ("<" | "<=") exp1() "}" { return null; }\r
391 | "+" exp=exp5() { return new ExpUnaryExpression(exp, "+"); }\r
392 | "-" exp=exp5() { return new ExpUnaryExpression(exp, "-"); }\r
393 | <NOT> exp=exp5() { return new ExpUnaryExpression(exp, "not"); }\r
394 | exp=exp5() { return exp; }\r
395 }\r
396 \r
397 ExpExpression exp5() : { Token tt; ExpExpression exp; }\r
398 { tt=<INT> { return new ExpIntegerLiteral(tt.image); }  \r
399 | "(" exp=exp() ")" { return exp; }\r
400 | "?" { return ExpQuestionMark.INSTANCE; }\r
401 | <SELF> exp=quals(ExpQuestionMark.INSTANCE) { return exp; }\r
402 | <IDENT> ("(" (exp() ("," exp())*)? ")")? quals(null) { return null; }\r
403 | tt=<STRING> { return new ExpStringLiteral(tt.image.substring(1, tt.image.length()-1)); }  \r
404 | tt=<FLOAT> { return new ExpFloatLiteral(tt.image); }  \r
405 | <TRUE> { return ExpBooleanLiteral.TRUE; }  \r
406 | <FALSE> { return ExpBooleanLiteral.FALSE; } \r
407 /* ... */\r
408 }\r
409 \r
410 ExpExpression quals(ExpExpression base) : {}\r
411 { ( "." <IDENT>\r
412   | "\\" <IDENT>\r
413   | "[" exp() (":" exp1())? "]" \r
414   )* { return base; }\r
415 }\r
416 \r
417 void statement() : {}\r
418 { <RETURN> (exp1())? ";"\r
419 | <IF> exp() <THEN> (statement())+ (<ELSE> (statement())+)? <END_IF> ";"\r
420 | LOOKAHEAD(2) <IDENT> quals(null) ":=" exp() ";"\r
421 | <REPEAT> \r
422    (<IDENT> ":=" exp1() <TO> exp1() (<BY> exp2())?)?\r
423    (<WHILE> exp())?\r
424    (<UNTIL> exp())? ";" \r
425    (statement())+ <END_REPEAT> ";"\r
426 | <CASE> exp() <OF> ( exp() ("," exp())* ":" statement() )* <END_CASE> ";"\r
427 | <BEGIN> (statement())+ <END> ";"\r
428 | <ESCAPE> ";"\r
429 | <SKIP_> ";"\r
430 | LOOKAHEAD(2) <IDENT> "(" (exp() ("," exp())*)? ")" ";"\r
431 | ";"\r
432 /* | ... */\r
433 }\r
434 \r
435 String[] idents() : { List<String> idents = new ArrayList<String>(2); Token tt; } \r
436 { tt=<IDENT> { idents.add(tt.image); } ("," tt=<IDENT> { idents.add(tt.image); })* \r
437         { return idents.toArray(new String[idents.size()]); }\r
438 }