]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - 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
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 (file)
index 0000000..d49980f
--- /dev/null
@@ -0,0 +1,351 @@
+options {\r
+  JDK_VERSION = "1.6";\r
+  STATIC = false;\r
+  IGNORE_CASE = false;\r
+}\r
+\r
+PARSER_BEGIN(DataParser)\r
+package org.simantics.databoard.parser;\r
+\r
+import org.simantics.databoard.parser.ast.type.*;\r
+import org.simantics.databoard.parser.ast.value.*;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.Collections;\r
+\r
+/**\r
+ * Parser for data type definitions.\r
+ * @author Hannu Niemist�\r
+ */\r
+public class DataParser {    \r
+}\r
+PARSER_END(DataParser)\r
+\r
+/*** Lexer *********************************************************/\r
+\r
+SKIP:\r
+{ <WHITESPACE: " " | "\n" | "\r" | "\t" > \r
+| <COMMENT1: "/*" (~["*"] | "*" ~["/"])* "*/" >  \r
+| <COMMENT2: "//" (~["\n"])* >\r
+}\r
+\r
+TOKEN:\r
+{ ";" | "(" | ")" | "?" | "[" | "]"\r
+| "{" | "}" | "|" | "&" | ":" \r
+| "," | ".." | "." | "=" | "<" | ">"\r
+| "type" | "true" | "false" | "null" | "map" | "referable"\r
+| <STRING: "\"" (~["\"", "\\", "\n"] | "\\" ~["\n"])* "\"">\r
+    { matchedToken.image = StringEscapeUtils.unescape(\r
+        matchedToken.image.substring(1,matchedToken.image.length()-1)); }\r
+| <LONG_STRING: "\"\"\"" (~["\""] | "\"" ~["\""] | "\"\"" ~["\""])* "\"\"\"">\r
+    { matchedToken.image = matchedToken.image.substring(3,matchedToken.image.length()-3); }\r
+| <#POSITIVE_INTEGER: (["0"-"9"])+ >\r
+| <INTEGER: ("-"|"+")? <POSITIVE_INTEGER> >\r
+| <FLOAT: \r
+    ("-")? \r
+    ( <POSITIVE_INTEGER> "." <POSITIVE_INTEGER> (["e","E"] <INTEGER>)?\r
+    | "." <POSITIVE_INTEGER> (["e","E"] <INTEGER>)?\r
+    | <POSITIVE_INTEGER> ["e","E"] <INTEGER>\r
+    | "NaN"\r
+    | "Infinity"\r
+    ) >\r
+| <IDENT: ["a"-"z","A"-"Z","_"] (["a"-"z","A"-"Z","_","0"-"9"])* >\r
+| <URI: "<" (~["<",">"])* ">"> \r
+    { matchedToken.image = matchedToken.image.substring(1,matchedToken.image.length()-1); }\r
+}\r
+\r
+/*** Type parser ***************************************************/\r
+\r
+List<AstTypeDefinition> typeDefinitions() : {\r
+    AstTypeDefinition def;\r
+    List<AstTypeDefinition> result = new ArrayList<AstTypeDefinition>();\r
+} {\r
+    ( def=typeDefinition() { result.add(def); } )* <EOF>\r
+    { return result; }\r
+}\r
+\r
+AstTypeDefinition typeDefinition() : {\r
+    Token name;\r
+    AstType type;\r
+} {\r
+    "type" name=<IDENT> "=" type=type() \r
+    { return new AstTypeDefinition(name.image, type); }  \r
+}\r
+\r
+AstType type() : {   \r
+    AstType type;\r
+} {\r
+    type=simpleType()\r
+    { return type; }\r
+  | type=unionType()\r
+    { return type; }\r
+}\r
+\r
+AstType unionType() : {\r
+    List<AstComponent> components = new ArrayList<AstComponent>(4);\r
+} {\r
+    ( "|" unionComponent(components) )+\r
+    { return new AstUnionType(components); }\r
+}\r
+\r
+private void unionComponent(List<AstComponent> components) : {\r
+    Token tag;\r
+    AstType type;\r
+} {\r
+    tag=<IDENT>\r
+    ( \r
+        type=simpleType() { components.add(new AstComponent(tag.image, type)); }\r
+      | { components.add(new AstComponent(tag.image, AstRecordType.EMPTY_RECORD)); }\r
+    ) \r
+}\r
+\r
+AstType simpleType() : {   \r
+    AstType type;\r
+} {\r
+    type=basicType()\r
+    ( "[" type=arraySuffix(type) )*\r
+    { return type; }\r
+}\r
+\r
+private AstType arraySuffix(AstType componentType) : {\r
+    Token t1, t2;\r
+    Integer v1;\r
+} {\r
+    "]" { \r
+        return new AstArrayType(componentType, null, null); \r
+    }\r
+  | ".." t1=<INTEGER> "]" {\r
+        v1 = Integer.parseInt(t1.image); \r
+        return new AstArrayType(componentType, null, v1); \r
+    }\r
+  | t1=<INTEGER> { v1 = Integer.parseInt(t1.image);  } \r
+    (\r
+        "]" { return new AstArrayType(componentType, v1, v1); }   \r
+      | ".." \r
+        (\r
+            "]" { return new AstArrayType(componentType, v1, null); }\r
+          | t2=<INTEGER> "]" {\r
+               return new AstArrayType(componentType, v1, Integer.parseInt(t2.image)); \r
+            }\r
+        ) \r
+    )          \r
+}\r
+\r
+AstType basicType() : { \r
+    AstType type;\r
+    boolean referable = false;\r
+} { \r
+    "(" type = tupleType() ")" { return type; }\r
+  | ("referable" {referable=true;})? \r
+    "{" type = recordType(referable) "}" { return type; }\r
+  | type = typeReference() { return type; }\r
+}\r
+\r
+AstType typeReference() : {\r
+    Token name;\r
+    List<AstType> parameters = Collections.emptyList();\r
+    List<AstAttribute> attributes = Collections.emptyList();\r
+} {\r
+    name=<IDENT> \r
+    ("("\r
+        { parameters = new ArrayList<AstType>(2);\r
+          attributes = new ArrayList<AstAttribute>(2); \r
+        } \r
+        parameter(parameters, attributes)\r
+        ("," parameter(parameters, attributes))*\r
+    ")")?\r
+    { \r
+        return new AstTypeReference(name.image, parameters, attributes); \r
+    }\r
+}\r
+\r
+private void parameter(List<AstType> parameters, List<AstAttribute> attributes) : {\r
+    Token key;\r
+    String value;\r
+    AstType type;\r
+} {\r
+    LOOKAHEAD(<IDENT> "=")\r
+    key=<IDENT> "=" value=attributeValue() { attributes.add(new AstAttribute(key.image, value)); }  \r
+  | type=type() { parameters.add(type); }\r
+}\r
+\r
+String numericValue() : {}\r
+{ (<INTEGER> | <FLOAT>)\r
+  { return token.image; }\r
+| "-" (<INTEGER> | <FLOAT>)\r
+  { return "-" + token.image; }\r
+}\r
+\r
+String range() : {\r
+  Token open, close;\r
+  String first = "", second = "";\r
+} {\r
+  ( "[" | "(" ) { open = token; }\r
+  ( first = numericValue() )?\r
+  ".."\r
+  ( second = numericValue() )?\r
+  ( "]" | ")" ) { close = token; }\r
+  { return open.image + first + ".." + second + close.image; }  \r
+}\r
+\r
+String attributeValue() : {\r
+    String str;\r
+} {\r
+  ( <STRING> \r
+  | "true"\r
+  | "false" \r
+  ) { return token.image; }\r
+| str=numericValue() { return str; }\r
+| str=range() { return str; }\r
+}\r
+\r
+AstType tupleType() : { \r
+  AstType type;\r
+  ArrayList<AstType> types;  \r
+} {    \r
+    type = type() \r
+    { types = new ArrayList<AstType>(3); types.add(type); }\r
+    ( "," type = type() { types.add(type); } )* \r
+    { \r
+        if(types.size()==1)\r
+            return types.get(0);\r
+        else\r
+            return new AstTupleType(types);\r
+    }\r
+  | { return new AstTupleType(Collections.<AstType>emptyList()); } \r
+}\r
+\r
+AstType recordType(boolean referable) : {\r
+    AstComponent component;\r
+    ArrayList<AstComponent> components; \r
+} {    \r
+    component = component() \r
+    { components = new ArrayList<AstComponent>(3); components.add(component); }\r
+    ( "," component = component() { components.add(component); } )*\r
+    { return new AstRecordType(referable, components); }\r
+  | { return new AstRecordType(referable, Collections.<AstComponent>emptyList()); }\r
+}\r
+\r
+AstComponent component() : {\r
+    Token field;\r
+    AstType type;\r
+} {\r
+    (field=<IDENT> | field="type" | field="referable") ":" type=type() \r
+    { return new AstComponent(field.image, type); }\r
+}\r
\r
+/*** Value parser **************************************************/\r
+\r
+List<AstValueDefinition> valueDefinitions() : {\r
+    AstValueDefinition def;\r
+    List<AstValueDefinition> result = new ArrayList<AstValueDefinition>();\r
+} {\r
+    ( def=valueDefinition() { result.add(def); } )* <EOF>\r
+    { return result; }\r
+}\r
+\r
+AstValueDefinition valueDefinition() : {\r
+    Token name;\r
+    AstValue value;\r
+    AstType type;\r
+} {\r
+    name=<IDENT> ":" type=type() "=" value=value() \r
+    { return new AstValueDefinition(name.image, type, value); }\r
+}\r
+\r
+AstValue value() : {\r
+    AstValue value;\r
+    AstType type;\r
+} {\r
+    value = basicValue()\r
+    ( ":" type = type()\r
+      { value = new AstVariant(value, type); } \r
+    )*\r
+    { return value; }\r
+}\r
+\r
+AstValue basicValue() : {\r
+    Token tag;\r
+    AstValue temp;\r
+} {\r
+    "null" { return AstNull.NULL; }\r
+  | <STRING> { return new AstString(token.image); }\r
+  | <LONG_STRING> { return new AstString(token.image); }\r
+  | <INTEGER> { return new AstInteger(token.image); }\r
+  | <FLOAT> { return new AstFloat(token.image); }\r
+  | "true" { return AstBoolean.TRUE; }\r
+  | "false" { return AstBoolean.FALSE; }\r
+  | "map" "{" temp=map() "}" { return temp; }\r
+  | "[" temp=array() "]" { return temp; }\r
+  | "{" temp=record() "}" { return temp; }\r
+  | "(" temp=tuple() ")" { return temp; }\r
+  | tag=<IDENT> \r
+    ( temp=basicValue() { return new AstTaggedValue(tag.image, temp); }\r
+    | { return new AstReference(tag.image); }  \r
+    ) \r
+}\r
+\r
+AstArray array() : {\r
+    ArrayList<AstValue> components;\r
+    AstValue value;\r
+} {\r
+    { components = new ArrayList<AstValue>(); }\r
+    value=value() { components.add(value); }\r
+    (","  value=value() { components.add(value); })*\r
+    { return new AstArray(components); }\r
+  | { return AstArray.EMPTY; }     \r
+}\r
+\r
+AstValue tuple() : {\r
+    ArrayList<AstValue> components;\r
+    AstValue value;\r
+} {\r
+    { components = new ArrayList<AstValue>(); }\r
+    value=value() { components.add(value); }\r
+    (","  value=value() { components.add(value); })*\r
+    { \r
+        if(components.size() == 1)\r
+            return components.get(0);\r
+        else\r
+            return new AstTuple(components); \r
+    }\r
+  | { return AstTuple.EMPTY; }     \r
+}\r
+\r
+AstRecord record() : {\r
+    ArrayList<AstComponentAssignment> components;\r
+    AstComponentAssignment assignment;\r
+} {\r
+    { components = new ArrayList<AstComponentAssignment>(); }\r
+    assignment=assignment() { components.add(assignment); }\r
+    (","  assignment=assignment() { components.add(assignment); })*\r
+    { return new AstRecord(components); }\r
+  | { return AstRecord.EMPTY; }     \r
+}\r
+\r
+AstMap map() : {\r
+    ArrayList<AstMapAssignment> components;\r
+    AstMapAssignment assignment;\r
+} {\r
+    { components = new ArrayList<AstMapAssignment>(); }\r
+    assignment=mapAssignment() { components.add(assignment); }\r
+    (","  assignment=mapAssignment() { components.add(assignment); })*\r
+    { return new AstMap(components); }\r
+  | { return AstMap.EMPTY; }     \r
+}\r
+\r
+AstComponentAssignment assignment() : {\r
+    Token name;\r
+    AstValue value;\r
+} {\r
+    name=<IDENT> "=" value=value() \r
+    { return new AstComponentAssignment(name.image, value); }\r
+}\r
+\r
+AstMapAssignment mapAssignment() : {\r
+    AstValue key;\r
+    AstValue value;\r
+} {\r
+    key=value() "=" value=value() \r
+    { return new AstMapAssignment(key, value); }\r
+}
\ No newline at end of file