]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/parser/DataParser.jj
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / parser / DataParser.jj
1 options {\r
2   JDK_VERSION = "1.6";\r
3   STATIC = false;\r
4   IGNORE_CASE = false;\r
5 }\r
6 \r
7 PARSER_BEGIN(DataParser)\r
8 package org.simantics.databoard.parser;\r
9 \r
10 import org.simantics.databoard.parser.ast.type.*;\r
11 import org.simantics.databoard.parser.ast.value.*;\r
12 import java.util.ArrayList;\r
13 import java.util.List;\r
14 import java.util.Collections;\r
15 \r
16 /**\r
17  * Parser for data type definitions.\r
18  * @author Hannu Niemist�\r
19  */\r
20 public class DataParser {    \r
21 }\r
22 PARSER_END(DataParser)\r
23 \r
24 /*** Lexer *********************************************************/\r
25 \r
26 SKIP:\r
27 { <WHITESPACE: " " | "\n" | "\r" | "\t" > \r
28 | <COMMENT1: "/*" (~["*"] | "*" ~["/"])* "*/" >  \r
29 | <COMMENT2: "//" (~["\n"])* >\r
30 }\r
31 \r
32 TOKEN:\r
33 { ";" | "(" | ")" | "?" | "[" | "]"\r
34 | "{" | "}" | "|" | "&" | ":" \r
35 | "," | ".." | "." | "=" | "<" | ">"\r
36 | "type" | "true" | "false" | "null" | "map" | "referable"\r
37 | <STRING: "\"" (~["\"", "\\", "\n"] | "\\" ~["\n"])* "\"">\r
38     { matchedToken.image = StringEscapeUtils.unescape(\r
39         matchedToken.image.substring(1,matchedToken.image.length()-1)); }\r
40 | <LONG_STRING: "\"\"\"" (~["\""] | "\"" ~["\""] | "\"\"" ~["\""])* "\"\"\"">\r
41     { matchedToken.image = matchedToken.image.substring(3,matchedToken.image.length()-3); }\r
42 | <#POSITIVE_INTEGER: (["0"-"9"])+ >\r
43 | <INTEGER: ("-"|"+")? <POSITIVE_INTEGER> >\r
44 | <FLOAT: \r
45     ("-")? \r
46     ( <POSITIVE_INTEGER> "." <POSITIVE_INTEGER> (["e","E"] <INTEGER>)?\r
47     | "." <POSITIVE_INTEGER> (["e","E"] <INTEGER>)?\r
48     | <POSITIVE_INTEGER> ["e","E"] <INTEGER>\r
49     | "NaN"\r
50     | "Infinity"\r
51     ) >\r
52 | <IDENT: ["a"-"z","A"-"Z","_"] (["a"-"z","A"-"Z","_","0"-"9"])* >\r
53 | <URI: "<" (~["<",">"])* ">"> \r
54     { matchedToken.image = matchedToken.image.substring(1,matchedToken.image.length()-1); }\r
55 }\r
56 \r
57 /*** Type parser ***************************************************/\r
58 \r
59 List<AstTypeDefinition> typeDefinitions() : {\r
60     AstTypeDefinition def;\r
61     List<AstTypeDefinition> result = new ArrayList<AstTypeDefinition>();\r
62 } {\r
63     ( def=typeDefinition() { result.add(def); } )* <EOF>\r
64     { return result; }\r
65 }\r
66 \r
67 AstTypeDefinition typeDefinition() : {\r
68     Token name;\r
69     AstType type;\r
70 } {\r
71     "type" name=<IDENT> "=" type=type() \r
72     { return new AstTypeDefinition(name.image, type); }  \r
73 }\r
74 \r
75 AstType type() : {   \r
76     AstType type;\r
77 } {\r
78     type=simpleType()\r
79     { return type; }\r
80   | type=unionType()\r
81     { return type; }\r
82 }\r
83 \r
84 AstType unionType() : {\r
85     List<AstComponent> components = new ArrayList<AstComponent>(4);\r
86 } {\r
87     ( "|" unionComponent(components) )+\r
88     { return new AstUnionType(components); }\r
89 }\r
90 \r
91 private void unionComponent(List<AstComponent> components) : {\r
92     Token tag;\r
93     AstType type;\r
94 } {\r
95     tag=<IDENT>\r
96     ( \r
97         type=simpleType() { components.add(new AstComponent(tag.image, type)); }\r
98       | { components.add(new AstComponent(tag.image, AstRecordType.EMPTY_RECORD)); }\r
99     ) \r
100 }\r
101 \r
102 AstType simpleType() : {   \r
103     AstType type;\r
104 } {\r
105     type=basicType()\r
106     ( "[" type=arraySuffix(type) )*\r
107     { return type; }\r
108 }\r
109 \r
110 private AstType arraySuffix(AstType componentType) : {\r
111     Token t1, t2;\r
112     Integer v1;\r
113 } {\r
114     "]" { \r
115         return new AstArrayType(componentType, null, null); \r
116     }\r
117   | ".." t1=<INTEGER> "]" {\r
118         v1 = Integer.parseInt(t1.image); \r
119         return new AstArrayType(componentType, null, v1); \r
120     }\r
121   | t1=<INTEGER> { v1 = Integer.parseInt(t1.image);  } \r
122     (\r
123         "]" { return new AstArrayType(componentType, v1, v1); }   \r
124       | ".." \r
125         (\r
126             "]" { return new AstArrayType(componentType, v1, null); }\r
127           | t2=<INTEGER> "]" {\r
128                return new AstArrayType(componentType, v1, Integer.parseInt(t2.image)); \r
129             }\r
130         ) \r
131     )          \r
132 }\r
133 \r
134 AstType basicType() : { \r
135     AstType type;\r
136     boolean referable = false;\r
137 } { \r
138     "(" type = tupleType() ")" { return type; }\r
139   | ("referable" {referable=true;})? \r
140     "{" type = recordType(referable) "}" { return type; }\r
141   | type = typeReference() { return type; }\r
142 }\r
143 \r
144 AstType typeReference() : {\r
145     Token name;\r
146     List<AstType> parameters = Collections.emptyList();\r
147     List<AstAttribute> attributes = Collections.emptyList();\r
148 } {\r
149     name=<IDENT> \r
150     ("("\r
151         { parameters = new ArrayList<AstType>(2);\r
152           attributes = new ArrayList<AstAttribute>(2); \r
153         } \r
154         parameter(parameters, attributes)\r
155         ("," parameter(parameters, attributes))*\r
156     ")")?\r
157     { \r
158         return new AstTypeReference(name.image, parameters, attributes); \r
159     }\r
160 }\r
161 \r
162 private void parameter(List<AstType> parameters, List<AstAttribute> attributes) : {\r
163     Token key;\r
164     String value;\r
165     AstType type;\r
166 } {\r
167     LOOKAHEAD(<IDENT> "=")\r
168     key=<IDENT> "=" value=attributeValue() { attributes.add(new AstAttribute(key.image, value)); }  \r
169   | type=type() { parameters.add(type); }\r
170 }\r
171 \r
172 String numericValue() : {}\r
173 { (<INTEGER> | <FLOAT>)\r
174   { return token.image; }\r
175 | "-" (<INTEGER> | <FLOAT>)\r
176   { return "-" + token.image; }\r
177 }\r
178 \r
179 String range() : {\r
180   Token open, close;\r
181   String first = "", second = "";\r
182 } {\r
183   ( "[" | "(" ) { open = token; }\r
184   ( first = numericValue() )?\r
185   ".."\r
186   ( second = numericValue() )?\r
187   ( "]" | ")" ) { close = token; }\r
188   { return open.image + first + ".." + second + close.image; }  \r
189 }\r
190 \r
191 String attributeValue() : {\r
192     String str;\r
193 } {\r
194   ( <STRING> \r
195   | "true"\r
196   | "false" \r
197   ) { return token.image; }\r
198 | str=numericValue() { return str; }\r
199 | str=range() { return str; }\r
200 }\r
201 \r
202 AstType tupleType() : { \r
203   AstType type;\r
204   ArrayList<AstType> types;  \r
205 } {    \r
206     type = type() \r
207     { types = new ArrayList<AstType>(3); types.add(type); }\r
208     ( "," type = type() { types.add(type); } )* \r
209     { \r
210         if(types.size()==1)\r
211             return types.get(0);\r
212         else\r
213             return new AstTupleType(types);\r
214     }\r
215   | { return new AstTupleType(Collections.<AstType>emptyList()); } \r
216 }\r
217 \r
218 AstType recordType(boolean referable) : {\r
219     AstComponent component;\r
220     ArrayList<AstComponent> components; \r
221 } {    \r
222     component = component() \r
223     { components = new ArrayList<AstComponent>(3); components.add(component); }\r
224     ( "," component = component() { components.add(component); } )*\r
225     { return new AstRecordType(referable, components); }\r
226   | { return new AstRecordType(referable, Collections.<AstComponent>emptyList()); }\r
227 }\r
228 \r
229 AstComponent component() : {\r
230     Token field;\r
231     AstType type;\r
232 } {\r
233     (field=<IDENT> | field="type" | field="referable") ":" type=type() \r
234     { return new AstComponent(field.image, type); }\r
235 }\r
236  \r
237 /*** Value parser **************************************************/\r
238 \r
239 List<AstValueDefinition> valueDefinitions() : {\r
240     AstValueDefinition def;\r
241     List<AstValueDefinition> result = new ArrayList<AstValueDefinition>();\r
242 } {\r
243     ( def=valueDefinition() { result.add(def); } )* <EOF>\r
244     { return result; }\r
245 }\r
246 \r
247 AstValueDefinition valueDefinition() : {\r
248     Token name;\r
249     AstValue value;\r
250     AstType type;\r
251 } {\r
252     name=<IDENT> ":" type=type() "=" value=value() \r
253     { return new AstValueDefinition(name.image, type, value); }\r
254 }\r
255 \r
256 AstValue value() : {\r
257     AstValue value;\r
258     AstType type;\r
259 } {\r
260     value = basicValue()\r
261     ( ":" type = type()\r
262       { value = new AstVariant(value, type); } \r
263     )*\r
264     { return value; }\r
265 }\r
266 \r
267 AstValue basicValue() : {\r
268     Token tag;\r
269     AstValue temp;\r
270 } {\r
271     "null" { return AstNull.NULL; }\r
272   | <STRING> { return new AstString(token.image); }\r
273   | <LONG_STRING> { return new AstString(token.image); }\r
274   | <INTEGER> { return new AstInteger(token.image); }\r
275   | <FLOAT> { return new AstFloat(token.image); }\r
276   | "true" { return AstBoolean.TRUE; }\r
277   | "false" { return AstBoolean.FALSE; }\r
278   | "map" "{" temp=map() "}" { return temp; }\r
279   | "[" temp=array() "]" { return temp; }\r
280   | "{" temp=record() "}" { return temp; }\r
281   | "(" temp=tuple() ")" { return temp; }\r
282   | tag=<IDENT> \r
283     ( temp=basicValue() { return new AstTaggedValue(tag.image, temp); }\r
284     | { return new AstReference(tag.image); }  \r
285     ) \r
286 }\r
287 \r
288 AstArray array() : {\r
289     ArrayList<AstValue> components;\r
290     AstValue value;\r
291 } {\r
292     { components = new ArrayList<AstValue>(); }\r
293     value=value() { components.add(value); }\r
294     (","  value=value() { components.add(value); })*\r
295     { return new AstArray(components); }\r
296   | { return AstArray.EMPTY; }     \r
297 }\r
298 \r
299 AstValue tuple() : {\r
300     ArrayList<AstValue> components;\r
301     AstValue value;\r
302 } {\r
303     { components = new ArrayList<AstValue>(); }\r
304     value=value() { components.add(value); }\r
305     (","  value=value() { components.add(value); })*\r
306     { \r
307         if(components.size() == 1)\r
308             return components.get(0);\r
309         else\r
310             return new AstTuple(components); \r
311     }\r
312   | { return AstTuple.EMPTY; }     \r
313 }\r
314 \r
315 AstRecord record() : {\r
316     ArrayList<AstComponentAssignment> components;\r
317     AstComponentAssignment assignment;\r
318 } {\r
319     { components = new ArrayList<AstComponentAssignment>(); }\r
320     assignment=assignment() { components.add(assignment); }\r
321     (","  assignment=assignment() { components.add(assignment); })*\r
322     { return new AstRecord(components); }\r
323   | { return AstRecord.EMPTY; }     \r
324 }\r
325 \r
326 AstMap map() : {\r
327     ArrayList<AstMapAssignment> components;\r
328     AstMapAssignment assignment;\r
329 } {\r
330     { components = new ArrayList<AstMapAssignment>(); }\r
331     assignment=mapAssignment() { components.add(assignment); }\r
332     (","  assignment=mapAssignment() { components.add(assignment); })*\r
333     { return new AstMap(components); }\r
334   | { return AstMap.EMPTY; }     \r
335 }\r
336 \r
337 AstComponentAssignment assignment() : {\r
338     Token name;\r
339     AstValue value;\r
340 } {\r
341     name=<IDENT> "=" value=value() \r
342     { return new AstComponentAssignment(name.image, value); }\r
343 }\r
344 \r
345 AstMapAssignment mapAssignment() : {\r
346     AstValue key;\r
347     AstValue value;\r
348 } {\r
349     key=value() "=" value=value() \r
350     { return new AstMapAssignment(key, value); }\r
351 }