7 PARSER_BEGIN(DataParser)
8 package org.simantics.databoard.parser;
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;
17 * Parser for data type definitions.
18 * @author Hannu Niemist�
20 public class DataParser {
22 PARSER_END(DataParser)
24 /*** Lexer *********************************************************/
27 { <WHITESPACE: " " | "\n" | "\r" | "\t" >
28 | <COMMENT1: "/*" (~["*"] | "*" ~["/"])* "*/" >
29 | <COMMENT2: "//" (~["\n"])* >
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> >
46 ( <POSITIVE_INTEGER> "." <POSITIVE_INTEGER> (["e","E"] <INTEGER>)?
47 | "." <POSITIVE_INTEGER> (["e","E"] <INTEGER>)?
48 | <POSITIVE_INTEGER> ["e","E"] <INTEGER>
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); }
57 /*** Type parser ***************************************************/
59 List<AstTypeDefinition> typeDefinitions() : {
60 AstTypeDefinition def;
61 List<AstTypeDefinition> result = new ArrayList<AstTypeDefinition>();
63 ( def=typeDefinition() { result.add(def); } )* <EOF>
67 AstTypeDefinition typeDefinition() : {
71 "type" name=<IDENT> "=" type=type()
72 { return new AstTypeDefinition(name.image, type); }
84 AstType unionType() : {
85 List<AstComponent> components = new ArrayList<AstComponent>(4);
87 ( "|" unionComponent(components) )+
88 { return new AstUnionType(components); }
91 private void unionComponent(List<AstComponent> components) : {
97 type=simpleType() { components.add(new AstComponent(tag.image, type)); }
98 | { components.add(new AstComponent(tag.image, AstRecordType.EMPTY_RECORD)); }
102 AstType simpleType() : {
106 ( "[" type=arraySuffix(type) )*
110 private AstType arraySuffix(AstType componentType) : {
115 return new AstArrayType(componentType, null, null);
117 | ".." t1=<INTEGER> "]" {
118 v1 = Integer.parseInt(t1.image);
119 return new AstArrayType(componentType, null, v1);
121 | t1=<INTEGER> { v1 = Integer.parseInt(t1.image); }
123 "]" { return new AstArrayType(componentType, v1, v1); }
126 "]" { return new AstArrayType(componentType, v1, null); }
128 return new AstArrayType(componentType, v1, Integer.parseInt(t2.image));
134 AstType basicType() : {
136 boolean referable = false;
138 "(" type = tupleType() ")" { return type; }
139 | ("referable" {referable=true;})?
140 "{" type = recordType(referable) "}" { return type; }
141 | type = typeReference() { return type; }
144 AstType typeReference() : {
146 List<AstType> parameters = Collections.emptyList();
147 List<AstAttribute> attributes = Collections.emptyList();
151 { parameters = new ArrayList<AstType>(2);
152 attributes = new ArrayList<AstAttribute>(2);
154 parameter(parameters, attributes)
155 ("," parameter(parameters, attributes))*
158 return new AstTypeReference(name.image, parameters, attributes);
162 private void parameter(List<AstType> parameters, List<AstAttribute> attributes) : {
167 LOOKAHEAD(<IDENT> "=")
168 key=<IDENT> "=" value=attributeValue() { attributes.add(new AstAttribute(key.image, value)); }
169 | type=type() { parameters.add(type); }
172 String numericValue() : {}
173 { (<INTEGER> | <FLOAT>)
174 { return token.image; }
175 | "-" (<INTEGER> | <FLOAT>)
176 { return "-" + token.image; }
181 String first = "", second = "";
183 ( "[" | "(" ) { open = token; }
184 ( first = numericValue() )?
186 ( second = numericValue() )?
187 ( "]" | ")" ) { close = token; }
188 { return open.image + first + ".." + second + close.image; }
191 String attributeValue() : {
197 ) { return token.image; }
198 | str=numericValue() { return str; }
199 | str=range() { return str; }
202 AstType tupleType() : {
204 ArrayList<AstType> types;
207 { types = new ArrayList<AstType>(3); types.add(type); }
208 ( "," type = type() { types.add(type); } )*
213 return new AstTupleType(types);
215 | { return new AstTupleType(Collections.<AstType>emptyList()); }
218 AstType recordType(boolean referable) : {
219 AstComponent component;
220 ArrayList<AstComponent> components;
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()); }
229 AstComponent component() : {
233 (field=<IDENT> | field="type" | field="referable") ":" type=type()
234 { return new AstComponent(field.image, type); }
237 /*** Value parser **************************************************/
239 List<AstValueDefinition> valueDefinitions() : {
240 AstValueDefinition def;
241 List<AstValueDefinition> result = new ArrayList<AstValueDefinition>();
243 ( def=valueDefinition() { result.add(def); } )* <EOF>
247 AstValueDefinition valueDefinition() : {
252 name=<IDENT> ":" type=type() "=" value=value()
253 { return new AstValueDefinition(name.image, type, value); }
262 { value = new AstVariant(value, type); }
267 AstValue basicValue() : {
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; }
283 ( temp=basicValue() { return new AstTaggedValue(tag.image, temp); }
284 | { return new AstReference(tag.image); }
289 ArrayList<AstValue> components;
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; }
300 ArrayList<AstValue> components;
303 { components = new ArrayList<AstValue>(); }
304 value=value() { components.add(value); }
305 ("," value=value() { components.add(value); })*
307 if(components.size() == 1)
308 return components.get(0);
310 return new AstTuple(components);
312 | { return AstTuple.EMPTY; }
315 AstRecord record() : {
316 ArrayList<AstComponentAssignment> components;
317 AstComponentAssignment assignment;
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; }
327 ArrayList<AstMapAssignment> components;
328 AstMapAssignment assignment;
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; }
337 AstComponentAssignment assignment() : {
341 name=<IDENT> "=" value=value()
342 { return new AstComponentAssignment(name.image, value); }
345 AstMapAssignment mapAssignment() : {
349 key=value() "=" value=value()
350 { return new AstMapAssignment(key, value); }