X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.databoard%2Fsrc%2Forg%2Fsimantics%2Fdataboard%2Fparser%2FDataParser.jj;fp=bundles%2Forg.simantics.databoard%2Fsrc%2Forg%2Fsimantics%2Fdataboard%2Fparser%2FDataParser.jj;h=d49980f713b35129fb45c0381eef96d92861308c;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/parser/DataParser.jj b/bundles/org.simantics.databoard/src/org/simantics/databoard/parser/DataParser.jj new file mode 100644 index 000000000..d49980f71 --- /dev/null +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/parser/DataParser.jj @@ -0,0 +1,351 @@ +options { + JDK_VERSION = "1.6"; + STATIC = false; + IGNORE_CASE = false; +} + +PARSER_BEGIN(DataParser) +package org.simantics.databoard.parser; + +import org.simantics.databoard.parser.ast.type.*; +import org.simantics.databoard.parser.ast.value.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Collections; + +/** + * Parser for data type definitions. + * @author Hannu Niemist� + */ +public class DataParser { +} +PARSER_END(DataParser) + +/*** Lexer *********************************************************/ + +SKIP: +{ +| +| +} + +TOKEN: +{ ";" | "(" | ")" | "?" | "[" | "]" +| "{" | "}" | "|" | "&" | ":" +| "," | ".." | "." | "=" | "<" | ">" +| "type" | "true" | "false" | "null" | "map" | "referable" +| + { matchedToken.image = StringEscapeUtils.unescape( + matchedToken.image.substring(1,matchedToken.image.length()-1)); } +| + { matchedToken.image = matchedToken.image.substring(3,matchedToken.image.length()-3); } +| <#POSITIVE_INTEGER: (["0"-"9"])+ > +| > +| "." (["e","E"] )? + | "." (["e","E"] )? + | ["e","E"] + | "NaN" + | "Infinity" + ) > +| +| "])* ">"> + { matchedToken.image = matchedToken.image.substring(1,matchedToken.image.length()-1); } +} + +/*** Type parser ***************************************************/ + +List typeDefinitions() : { + AstTypeDefinition def; + List result = new ArrayList(); +} { + ( def=typeDefinition() { result.add(def); } )* + { return result; } +} + +AstTypeDefinition typeDefinition() : { + Token name; + AstType type; +} { + "type" name= "=" type=type() + { return new AstTypeDefinition(name.image, type); } +} + +AstType type() : { + AstType type; +} { + type=simpleType() + { return type; } + | type=unionType() + { return type; } +} + +AstType unionType() : { + List components = new ArrayList(4); +} { + ( "|" unionComponent(components) )+ + { return new AstUnionType(components); } +} + +private void unionComponent(List components) : { + Token tag; + AstType type; +} { + tag= + ( + type=simpleType() { components.add(new AstComponent(tag.image, type)); } + | { components.add(new AstComponent(tag.image, AstRecordType.EMPTY_RECORD)); } + ) +} + +AstType simpleType() : { + AstType type; +} { + type=basicType() + ( "[" type=arraySuffix(type) )* + { return type; } +} + +private AstType arraySuffix(AstType componentType) : { + Token t1, t2; + Integer v1; +} { + "]" { + return new AstArrayType(componentType, null, null); + } + | ".." t1= "]" { + v1 = Integer.parseInt(t1.image); + return new AstArrayType(componentType, null, v1); + } + | t1= { v1 = Integer.parseInt(t1.image); } + ( + "]" { return new AstArrayType(componentType, v1, v1); } + | ".." + ( + "]" { return new AstArrayType(componentType, v1, null); } + | t2= "]" { + return new AstArrayType(componentType, v1, Integer.parseInt(t2.image)); + } + ) + ) +} + +AstType basicType() : { + AstType type; + boolean referable = false; +} { + "(" type = tupleType() ")" { return type; } + | ("referable" {referable=true;})? + "{" type = recordType(referable) "}" { return type; } + | type = typeReference() { return type; } +} + +AstType typeReference() : { + Token name; + List parameters = Collections.emptyList(); + List attributes = Collections.emptyList(); +} { + name= + ("(" + { parameters = new ArrayList(2); + attributes = new ArrayList(2); + } + parameter(parameters, attributes) + ("," parameter(parameters, attributes))* + ")")? + { + return new AstTypeReference(name.image, parameters, attributes); + } +} + +private void parameter(List parameters, List attributes) : { + Token key; + String value; + AstType type; +} { + LOOKAHEAD( "=") + key= "=" value=attributeValue() { attributes.add(new AstAttribute(key.image, value)); } + | type=type() { parameters.add(type); } +} + +String numericValue() : {} +{ ( | ) + { return token.image; } +| "-" ( | ) + { return "-" + token.image; } +} + +String range() : { + Token open, close; + String first = "", second = ""; +} { + ( "[" | "(" ) { open = token; } + ( first = numericValue() )? + ".." + ( second = numericValue() )? + ( "]" | ")" ) { close = token; } + { return open.image + first + ".." + second + close.image; } +} + +String attributeValue() : { + String str; +} { + ( + | "true" + | "false" + ) { return token.image; } +| str=numericValue() { return str; } +| str=range() { return str; } +} + +AstType tupleType() : { + AstType type; + ArrayList types; +} { + type = type() + { types = new ArrayList(3); types.add(type); } + ( "," type = type() { types.add(type); } )* + { + if(types.size()==1) + return types.get(0); + else + return new AstTupleType(types); + } + | { return new AstTupleType(Collections.emptyList()); } +} + +AstType recordType(boolean referable) : { + AstComponent component; + ArrayList components; +} { + component = component() + { components = new ArrayList(3); components.add(component); } + ( "," component = component() { components.add(component); } )* + { return new AstRecordType(referable, components); } + | { return new AstRecordType(referable, Collections.emptyList()); } +} + +AstComponent component() : { + Token field; + AstType type; +} { + (field= | field="type" | field="referable") ":" type=type() + { return new AstComponent(field.image, type); } +} + +/*** Value parser **************************************************/ + +List valueDefinitions() : { + AstValueDefinition def; + List result = new ArrayList(); +} { + ( def=valueDefinition() { result.add(def); } )* + { return result; } +} + +AstValueDefinition valueDefinition() : { + Token name; + AstValue value; + AstType type; +} { + name= ":" type=type() "=" value=value() + { return new AstValueDefinition(name.image, type, value); } +} + +AstValue value() : { + AstValue value; + AstType type; +} { + value = basicValue() + ( ":" type = type() + { value = new AstVariant(value, type); } + )* + { return value; } +} + +AstValue basicValue() : { + Token tag; + AstValue temp; +} { + "null" { return AstNull.NULL; } + | { return new AstString(token.image); } + | { return new AstString(token.image); } + | { return new AstInteger(token.image); } + | { return new AstFloat(token.image); } + | "true" { return AstBoolean.TRUE; } + | "false" { return AstBoolean.FALSE; } + | "map" "{" temp=map() "}" { return temp; } + | "[" temp=array() "]" { return temp; } + | "{" temp=record() "}" { return temp; } + | "(" temp=tuple() ")" { return temp; } + | tag= + ( temp=basicValue() { return new AstTaggedValue(tag.image, temp); } + | { return new AstReference(tag.image); } + ) +} + +AstArray array() : { + ArrayList components; + AstValue value; +} { + { components = new ArrayList(); } + value=value() { components.add(value); } + ("," value=value() { components.add(value); })* + { return new AstArray(components); } + | { return AstArray.EMPTY; } +} + +AstValue tuple() : { + ArrayList components; + AstValue value; +} { + { components = new ArrayList(); } + value=value() { components.add(value); } + ("," value=value() { components.add(value); })* + { + if(components.size() == 1) + return components.get(0); + else + return new AstTuple(components); + } + | { return AstTuple.EMPTY; } +} + +AstRecord record() : { + ArrayList components; + AstComponentAssignment assignment; +} { + { components = new ArrayList(); } + assignment=assignment() { components.add(assignment); } + ("," assignment=assignment() { components.add(assignment); })* + { return new AstRecord(components); } + | { return AstRecord.EMPTY; } +} + +AstMap map() : { + ArrayList components; + AstMapAssignment assignment; +} { + { components = new ArrayList(); } + assignment=mapAssignment() { components.add(assignment); } + ("," assignment=mapAssignment() { components.add(assignment); })* + { return new AstMap(components); } + | { return AstMap.EMPTY; } +} + +AstComponentAssignment assignment() : { + Token name; + AstValue value; +} { + name= "=" value=value() + { return new AstComponentAssignment(name.image, value); } +} + +AstMapAssignment mapAssignment() : { + AstValue key; + AstValue value; +} { + key=value() "=" value=value() + { return new AstMapAssignment(key, value); } +} \ No newline at end of file