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