You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2019/05/20 09:27:41 UTC

[plc4x] branch feature/code-gen updated: - Implemented a first parser built on top of the "immaginery format" and a modified version of Julians antlr4 grammar.

This is an automated email from the ASF dual-hosted git repository.

cdutz pushed a commit to branch feature/code-gen
in repository https://gitbox.apache.org/repos/asf/plc4x.git


The following commit(s) were added to refs/heads/feature/code-gen by this push:
     new fb24433  - Implemented a first parser built on top of the "immaginery format" and a modified version of Julians antlr4 grammar.
fb24433 is described below

commit fb2443398c57595546979185fe59537a2a24c4ed
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Mon May 20 11:27:33 2019 +0200

    - Implemented a first parser built on top of the "immaginery format" and a modified version of Julians antlr4 grammar.
---
 sandbox/plc4x-maven-plugin/pom.xml                 |  25 +++
 .../codegenerator/parser/imaginary/Imaginary.g4    | 190 +++++++++++++++++++
 .../model/{Type.java => ComplexType.java}          |  23 ++-
 .../{Type.java => DiscriminatedComplexType.java}   |  17 +-
 .../plc4x/plugins/codegenerator/model/Type.java    |  10 +
 .../model/{Type.java => fields/ArrayField.java}    |  32 +++-
 .../model/{Type.java => fields/ConstField.java}    |  22 ++-
 .../{Type.java => fields/DiscriminatorField.java}  |  14 +-
 .../model/{Type.java => fields/Field.java}         |  15 +-
 .../model/{Type.java => fields/ImplicitField.java} |  22 ++-
 .../model/{Type.java => fields/OptionalField.java} |  20 +-
 .../model/{Type.java => fields/ReservedField.java} |  14 +-
 .../model/{Type.java => fields/SimpleField.java}   |  14 +-
 .../model/{Type.java => fields/SwitchField.java}   |  29 ++-
 .../parser/MessageFormatListener.java              | 182 ++++++++++++++++++
 .../codegenerator/parser/MessageFormatParser.java  |  55 ++++++
 .../parser/ManualMessageFormatParserTest.java}     |  16 +-
 .../src/test/resources/specs/s7.spec               | 205 +++++++++++++++++++++
 18 files changed, 829 insertions(+), 76 deletions(-)

diff --git a/sandbox/plc4x-maven-plugin/pom.xml b/sandbox/plc4x-maven-plugin/pom.xml
index 44a6e6d..ad9e8ca 100644
--- a/sandbox/plc4x-maven-plugin/pom.xml
+++ b/sandbox/plc4x-maven-plugin/pom.xml
@@ -46,6 +46,7 @@
 
   <properties>
     <maven.version>3.3.9</maven.version>
+    <antlr.version>4.7.2</antlr.version>
   </properties>
 
   <dependencies>
@@ -76,6 +77,12 @@
     </dependency>
 
     <dependency>
+      <groupId>org.antlr</groupId>
+      <artifactId>antlr4-runtime</artifactId>
+      <version>${antlr.version}</version>
+    </dependency>
+
+    <dependency>
       <groupId>org.apache.maven</groupId>
       <artifactId>maven-plugin-api</artifactId>
       <version>${maven.version}</version>
@@ -159,11 +166,29 @@
           <artifactId>maven-invoker-plugin</artifactId>
           <version>3.1.0</version>
         </plugin>
+        <plugin>
+          <groupId>org.antlr</groupId>
+          <artifactId>antlr4-maven-plugin</artifactId>
+          <version>${antlr.version}</version>
+        </plugin>
       </plugins>
     </pluginManagement>
 
     <plugins>
       <plugin>
+        <groupId>org.antlr</groupId>
+        <artifactId>antlr4-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>antlr</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>antlr4</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-plugin-plugin</artifactId>
         <version>3.6.0</version>
diff --git a/sandbox/plc4x-maven-plugin/src/main/antlr4/org/apache/plc4x/codegenerator/parser/imaginary/Imaginary.g4 b/sandbox/plc4x-maven-plugin/src/main/antlr4/org/apache/plc4x/codegenerator/parser/imaginary/Imaginary.g4
new file mode 100644
index 0000000..84368c1
--- /dev/null
+++ b/sandbox/plc4x-maven-plugin/src/main/antlr4/org/apache/plc4x/codegenerator/parser/imaginary/Imaginary.g4
@@ -0,0 +1,190 @@
+grammar Imaginary;
+
+file
+ : complexTypeDefinition* EOF
+ ;
+
+complexTypeDefinition
+ : COMMENT
+ | LBRACKET complexType RBRACKET
+ ;
+
+complexType
+ : K_TYPE name=idExpression fieldDefinition+
+ | K_DISCRIMINATED_TYPE name=idExpression length='[length]'? fieldDefinition+
+ ;
+
+
+fieldDefinition
+ : LBRACKET field RBRACKET
+ ;
+
+field
+ : arrayField
+ | constField
+ | contextField
+ | discriminatorField
+ | embeddedField
+ | simpleField
+ | implicitField
+ | optionalField
+ | reservedField
+ | typeSwitchField
+ ;
+
+arrayField
+ : K_ARRAY type=typeReference name=idExpression lengthType=arrayType lengthExpression=expression
+ ;
+
+constField
+ : K_CONST type=dataType name=idExpression expected=expression
+ ;
+
+contextField
+ : K_CONTEXT type=dataType name=idExpression expression
+ ;
+
+discriminatorField
+ : K_DISCRIMINATOR type=dataType name=idExpression
+ ;
+
+embeddedField
+ : K_EMBEDDED name=idExpression LCBRACKET context RCBRACKET
+ ;
+
+simpleField
+ : K_FIELD type=dataType name=idExpression
+ ;
+
+implicitField
+ : K_IMPLICIT type=dataType name=idExpression serializationExpression=expression
+ ;
+
+optionalField
+ : K_OPTIONAL_FIELD type=typeReference name=idExpression condition=expression
+ ;
+
+reservedField
+ : K_RESERVED type=dataType expected=expression
+ ;
+
+typeSwitchField
+ : K_TYPE_SWITCH discriminator=idExpression caseStatement*
+ ;
+
+
+typeReference
+ : IDENTIFIER
+ | dataType
+ ;
+
+caseStatement
+ : LBRACKET discriminatorValues=multipleExpressions name=IDENTIFIER fieldDefinition+ RBRACKET
+ ;
+
+dataType
+ : 'bit'
+ | 'uint7'
+ | K_UINT8
+ | K_UINT16
+ ;
+
+expression
+ : TICK expr=innerExpression TICK
+ ;
+
+multipleExpressions
+ : expression (',' expression)*
+ ;
+
+innerExpression
+ : HEX_LITERAL
+ | INTEGER_LITERAL
+ | IDENTIFIER   // Variable reference
+ | innerExpression '.' IDENTIFIER // Field Reference
+ | innerExpression BinaryOperator innerExpression  // Addition
+ | '(' innerExpression ')'
+ ;
+
+context
+ : IDENTIFIER ':' expression (',' IDENTIFIER ':' expression)*
+ ;
+
+COMMENT
+ : K_COMMENT [a-zA-Z0-9,.'":()/ \t\r\n\u000C-]*
+ | '//' [a-zA-Z0-9,.'":()/ \t-]*
+ ;
+
+INTEGER_LITERAL
+ : [0-9]+
+ ;
+
+HEX_LITERAL
+ : HexNumeral
+ ;
+
+fragment HexNumeral
+ : '0' [xX] HexDigit HexDigit?;
+
+fragment HexDigit
+ : [0-9a-fA-F]
+;
+
+modifier
+ : K_CONST
+ | K_RESERVED
+ | K_IMPLICIT
+ | K_EMBEDDED
+ ;
+
+arrayType
+ : K_COUNT
+ | K_LENGTH
+ ;
+
+idExpression
+ : TICK id=IDENTIFIER TICK
+ ;
+
+fragment K_COMMENT : '<--';
+K_ARRAY : 'arrayField';
+K_CONST : 'const';
+K_CONTEXT : 'context';
+K_DISCRIMINATED_TYPE : 'discriminatedType';
+K_DISCRIMINATOR : 'discriminator';
+K_EMBEDDED : 'embedded';
+K_FIELD : 'field';
+K_IMPLICIT : 'implicit';
+K_OPTIONAL_FIELD : 'optionalField';
+K_RESERVED : 'reserved';
+K_TYPE : 'type';
+K_TYPE_SWITCH : 'typeSwitch';
+
+K_COUNT : 'count';
+K_LENGTH : 'length';
+
+K_UINT8 : 'uint8';
+K_UINT16 : 'uint16';
+
+TICK : '\'';
+TIMES : 'x';
+LBRACKET : '[';
+RBRACKET : ']';
+LCBRACKET : '{';
+RCBRACKET : '}';
+
+BinaryOperator
+ : '+'
+ | '-'
+ | '=='
+ ;
+
+ZERO : '0';
+HEX_VALUE : [0-9A-F];
+
+IDENTIFIER
+ : [A-Za-z0-9_-]+
+ ;
+
+WS  :  [ \t\r\n\u000C]+ -> skip
+;
\ No newline at end of file
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/ComplexType.java
similarity index 62%
copy from sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
copy to sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/ComplexType.java
index 949c181..9613de4 100644
--- a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/ComplexType.java
@@ -19,16 +19,27 @@
 
 package org.apache.plc4x.plugins.codegenerator.model;
 
-public abstract class Type {
+import org.apache.plc4x.plugins.codegenerator.model.fields.Field;
 
-    private final String name;
+import java.util.List;
 
-    public Type(String name) {
-        this.name = name;
+public class ComplexType extends Type {
+
+    private final boolean isAbstract;
+    private final List<Field> fields;
+
+    public ComplexType(String name, boolean isAbstract, List<Field> fields) {
+        super(name);
+        this.isAbstract = isAbstract;
+        this.fields = fields;
+    }
+
+    public boolean isAbstract() {
+        return isAbstract;
     }
 
-    public String getName() {
-        return name;
+    public List<Field> getFields() {
+        return fields;
     }
 
 }
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/DiscriminatedComplexType.java
similarity index 64%
copy from sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
copy to sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/DiscriminatedComplexType.java
index 949c181..247f228 100644
--- a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/DiscriminatedComplexType.java
@@ -19,16 +19,21 @@
 
 package org.apache.plc4x.plugins.codegenerator.model;
 
-public abstract class Type {
+import org.apache.plc4x.plugins.codegenerator.model.fields.Field;
 
-    private final String name;
+import java.util.List;
 
-    public Type(String name) {
-        this.name = name;
+public class DiscriminatedComplexType extends ComplexType {
+
+    private final String[] discriminatorValues;
+
+    public DiscriminatedComplexType(String name, String[] discriminatorValues, List<Field> fields) {
+        super(name, false, fields);
+        this.discriminatorValues = discriminatorValues;
     }
 
-    public String getName() {
-        return name;
+    public String[] getDiscriminatorValues() {
+        return discriminatorValues;
     }
 
 }
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
index 949c181..80fa313 100644
--- a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
@@ -22,13 +22,23 @@ package org.apache.plc4x.plugins.codegenerator.model;
 public abstract class Type {
 
     private final String name;
+    private Type parentType;
 
     public Type(String name) {
         this.name = name;
+        this.parentType = null;
     }
 
     public String getName() {
         return name;
     }
 
+    public Type getParentType() {
+        return parentType;
+    }
+
+    public void setParentType(Type parentType) {
+        this.parentType = parentType;
+    }
+
 }
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/ArrayField.java
similarity index 53%
copy from sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
copy to sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/ArrayField.java
index 949c181..0ad1b8c 100644
--- a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/ArrayField.java
@@ -17,18 +17,44 @@
  under the License.
  */
 
-package org.apache.plc4x.plugins.codegenerator.model;
+package org.apache.plc4x.plugins.codegenerator.model.fields;
 
-public abstract class Type {
+import org.apache.plc4x.plugins.codegenerator.model.Type;
 
+public class ArrayField implements Field {
+
+    private final String typeName;
     private final String name;
+    private final LengthType lengthType;
+    private final String lengthExpression;
+
 
-    public Type(String name) {
+    public ArrayField(String typeName, String name, LengthType lengthType, String lengthExpression) {
+        this.typeName = typeName;
         this.name = name;
+        this.lengthType = lengthType;
+        this.lengthExpression = lengthExpression;
+    }
+
+    public String getTypeName() {
+        return typeName;
     }
 
     public String getName() {
         return name;
     }
 
+    public LengthType getLengthType() {
+        return lengthType;
+    }
+
+    public String getLengthExpression() {
+        return lengthExpression;
+    }
+
+    public static enum LengthType {
+        COUNT,
+        LENGTH
+    }
+
 }
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/ConstField.java
similarity index 61%
copy from sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
copy to sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/ConstField.java
index 949c181..cb94688 100644
--- a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/ConstField.java
@@ -17,18 +17,26 @@
  under the License.
  */
 
-package org.apache.plc4x.plugins.codegenerator.model;
+package org.apache.plc4x.plugins.codegenerator.model.fields;
 
-public abstract class Type {
+import org.apache.plc4x.plugins.codegenerator.model.Type;
 
-    private final String name;
+public class ConstField implements Field {
 
-    public Type(String name) {
-        this.name = name;
+    private final Type type;
+    private final Object referenceValue;
+
+    public ConstField(Type type, Object referenceValue) {
+        this.type = type;
+        this.referenceValue = referenceValue;
+    }
+
+    public Type getType() {
+        return type;
     }
 
-    public String getName() {
-        return name;
+    public Object getReferenceValue() {
+        return referenceValue;
     }
 
 }
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/DiscriminatorField.java
similarity index 72%
copy from sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
copy to sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/DiscriminatorField.java
index 949c181..b1dab7a 100644
--- a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/DiscriminatorField.java
@@ -17,16 +17,24 @@
  under the License.
  */
 
-package org.apache.plc4x.plugins.codegenerator.model;
+package org.apache.plc4x.plugins.codegenerator.model.fields;
 
-public abstract class Type {
+import org.apache.plc4x.plugins.codegenerator.model.Type;
 
+public class DiscriminatorField implements Field {
+
+    private final Type type;
     private final String name;
 
-    public Type(String name) {
+    public DiscriminatorField(Type type, String name) {
+        this.type = type;
         this.name = name;
     }
 
+    public Type getType() {
+        return type;
+    }
+
     public String getName() {
         return name;
     }
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/Field.java
similarity index 76%
copy from sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
copy to sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/Field.java
index 949c181..59c7c93 100644
--- a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/Field.java
@@ -17,18 +17,7 @@
  under the License.
  */
 
-package org.apache.plc4x.plugins.codegenerator.model;
-
-public abstract class Type {
-
-    private final String name;
-
-    public Type(String name) {
-        this.name = name;
-    }
-
-    public String getName() {
-        return name;
-    }
+package org.apache.plc4x.plugins.codegenerator.model.fields;
 
+public interface Field {
 }
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/ImplicitField.java
similarity index 59%
copy from sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
copy to sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/ImplicitField.java
index 949c181..7a1d671 100644
--- a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/ImplicitField.java
@@ -17,18 +17,26 @@
  under the License.
  */
 
-package org.apache.plc4x.plugins.codegenerator.model;
+package org.apache.plc4x.plugins.codegenerator.model.fields;
 
-public abstract class Type {
+import org.apache.plc4x.plugins.codegenerator.model.Type;
 
-    private final String name;
+public class ImplicitField implements Field {
 
-    public Type(String name) {
-        this.name = name;
+    private final Type type;
+    private final String serializationExpression;
+
+    public ImplicitField(Type type, String serializationExpression) {
+        this.type = type;
+        this.serializationExpression = serializationExpression;
+    }
+
+    public Type getType() {
+        return type;
     }
 
-    public String getName() {
-        return name;
+    public String getSerializationExpression() {
+        return serializationExpression;
     }
 
 }
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/OptionalField.java
similarity index 62%
copy from sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
copy to sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/OptionalField.java
index 949c181..63947fa 100644
--- a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/OptionalField.java
@@ -17,18 +17,32 @@
  under the License.
  */
 
-package org.apache.plc4x.plugins.codegenerator.model;
+package org.apache.plc4x.plugins.codegenerator.model.fields;
 
-public abstract class Type {
+import org.apache.plc4x.plugins.codegenerator.model.Type;
 
+public class OptionalField implements Field {
+
+    private final Type type;
     private final String name;
+    private final String conditionExpression;
 
-    public Type(String name) {
+    public OptionalField(Type type, String name, String conditionExpression) {
+        this.type = type;
         this.name = name;
+        this.conditionExpression = conditionExpression;
+    }
+
+    public Type getType() {
+        return type;
     }
 
     public String getName() {
         return name;
     }
 
+    public String getConditionExpression() {
+        return conditionExpression;
+    }
+
 }
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/ReservedField.java
similarity index 74%
copy from sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
copy to sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/ReservedField.java
index 949c181..53a8808 100644
--- a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/ReservedField.java
@@ -17,18 +17,14 @@
  under the License.
  */
 
-package org.apache.plc4x.plugins.codegenerator.model;
+package org.apache.plc4x.plugins.codegenerator.model.fields;
 
-public abstract class Type {
+import org.apache.plc4x.plugins.codegenerator.model.Type;
 
-    private final String name;
+public class ReservedField extends ConstField {
 
-    public Type(String name) {
-        this.name = name;
-    }
-
-    public String getName() {
-        return name;
+    public ReservedField(Type type, Object referenceValue) {
+        super(type, referenceValue);
     }
 
 }
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/SimpleField.java
similarity index 73%
copy from sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
copy to sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/SimpleField.java
index 949c181..d412ee7 100644
--- a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/SimpleField.java
@@ -17,16 +17,24 @@
  under the License.
  */
 
-package org.apache.plc4x.plugins.codegenerator.model;
+package org.apache.plc4x.plugins.codegenerator.model.fields;
 
-public abstract class Type {
+import org.apache.plc4x.plugins.codegenerator.model.Type;
 
+public class SimpleField implements Field {
+
+    private final Type type;
     private final String name;
 
-    public Type(String name) {
+    public SimpleField(Type type, String name) {
+        this.type = type;
         this.name = name;
     }
 
+    public Type getType() {
+        return type;
+    }
+
     public String getName() {
         return name;
     }
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/SwitchField.java
similarity index 52%
copy from sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
copy to sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/SwitchField.java
index 949c181..78703b1 100644
--- a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/fields/SwitchField.java
@@ -17,18 +17,33 @@
  under the License.
  */
 
-package org.apache.plc4x.plugins.codegenerator.model;
+package org.apache.plc4x.plugins.codegenerator.model.fields;
 
-public abstract class Type {
+import org.apache.plc4x.plugins.codegenerator.model.DiscriminatedComplexType;
 
-    private final String name;
+import java.util.LinkedList;
+import java.util.List;
 
-    public Type(String name) {
-        this.name = name;
+public class SwitchField implements Field {
+
+    private final String discriminatorName;
+    private final List<DiscriminatedComplexType> cases;
+
+    public SwitchField(String discriminatorName) {
+        this.discriminatorName = discriminatorName;
+        cases = new LinkedList<>();
+    }
+
+    public String getDiscriminatorName() {
+        return discriminatorName;
+    }
+
+    public void addCase(DiscriminatedComplexType caseType) {
+        cases.add(caseType);
     }
 
-    public String getName() {
-        return name;
+    public List<DiscriminatedComplexType> getCases() {
+        return cases;
     }
 
 }
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/parser/MessageFormatListener.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/parser/MessageFormatListener.java
new file mode 100644
index 0000000..a98aa91
--- /dev/null
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/parser/MessageFormatListener.java
@@ -0,0 +1,182 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+package org.apache.plc4x.plugins.codegenerator.parser;
+
+import org.apache.plc4x.codegenerator.parser.imaginary.ImaginaryBaseListener;
+import org.apache.plc4x.codegenerator.parser.imaginary.ImaginaryParser;
+import org.apache.plc4x.plugins.codegenerator.model.ComplexType;
+import org.apache.plc4x.plugins.codegenerator.model.DiscriminatedComplexType;
+import org.apache.plc4x.plugins.codegenerator.model.SimpleType;
+import org.apache.plc4x.plugins.codegenerator.model.fields.*;
+
+import java.util.*;
+
+public class MessageFormatListener extends ImaginaryBaseListener {
+
+    private Stack<List<Field>> parserContexts;
+    private Map<String, ComplexType> complexTypes;
+
+    public Map<String, ComplexType> getComplexTypes() {
+        return complexTypes;
+    }
+
+    @Override
+    public void enterFile(ImaginaryParser.FileContext ctx) {
+        parserContexts = new Stack<>();
+        complexTypes = new HashMap<>();
+    }
+
+    @Override
+    public void enterComplexType(ImaginaryParser.ComplexTypeContext ctx) {
+        List<Field> parserContext = new LinkedList<>();
+        parserContexts.push(parserContext);
+    }
+
+    @Override
+    public void exitComplexType(ImaginaryParser.ComplexTypeContext ctx) {
+        String typeName = ctx.name.id.getText();
+        boolean abstractType = ctx.K_DISCRIMINATED_TYPE() != null;
+        ComplexType field = new ComplexType(typeName, abstractType, parserContexts.peek());
+        complexTypes.put(typeName, field);
+        parserContexts.pop();
+    }
+
+    @Override
+    public void enterArrayField(ImaginaryParser.ArrayFieldContext ctx) {
+        String typeName = ctx.type.getText();
+        String name = ctx.name.id.getText();
+        ArrayField.LengthType lengthType;
+        if(ctx.lengthType.K_COUNT() != null) {
+            lengthType = ArrayField.LengthType.COUNT;
+        } else {
+            lengthType = ArrayField.LengthType.LENGTH;
+        }
+        String lengthExpression = ctx.lengthExpression.getText();
+        Field field = new ArrayField(typeName, name, lengthType, lengthExpression);
+        parserContexts.peek().add(field);
+    }
+
+    @Override
+    public void enterConstField(ImaginaryParser.ConstFieldContext ctx) {
+        SimpleType type = new SimpleType(ctx.type.getText());
+        String expected = ctx.expected.getText();
+        Field field = new ConstField(type, expected);
+        parserContexts.peek().add(field);
+    }
+
+    @Override
+    public void enterContextField(ImaginaryParser.ContextFieldContext ctx) {
+        // This field type just adds something to the context (No parsing involved)
+        // TODO: Implement
+    }
+
+    @Override
+    public void enterDiscriminatorField(ImaginaryParser.DiscriminatorFieldContext ctx) {
+        SimpleType type = new SimpleType(ctx.type.getText());
+        String name = ctx.name.getText();
+        Field field = new DiscriminatorField(type, name);
+        parserContexts.peek().add(field);
+    }
+
+    @Override
+    public void enterEmbeddedField(ImaginaryParser.EmbeddedFieldContext ctx) {
+        super.enterEmbeddedField(ctx);
+        // TODO: Implement
+    }
+
+    @Override
+    public void enterSimpleField(ImaginaryParser.SimpleFieldContext ctx) {
+        SimpleType type = new SimpleType(ctx.type.getText());
+        String name = ctx.name.getText();
+        Field field = new SimpleField(type, name);
+        parserContexts.peek().add(field);
+    }
+
+    @Override
+    public void enterImplicitField(ImaginaryParser.ImplicitFieldContext ctx) {
+        SimpleType type = new SimpleType(ctx.type.getText());
+        String serializationExpression = ctx.serializationExpression.getText();
+        Field field = new ImplicitField(type, serializationExpression);
+        parserContexts.peek().add(field);
+    }
+
+    @Override
+    public void enterOptionalField(ImaginaryParser.OptionalFieldContext ctx) {
+        SimpleType type = new SimpleType(ctx.type.getText());
+        String name = ctx.name.getText();
+        String conditionExpression = ctx.condition.expr.getText();
+        Field field = new OptionalField(type, name, conditionExpression);
+        parserContexts.peek().add(field);
+    }
+
+    @Override
+    public void enterReservedField(ImaginaryParser.ReservedFieldContext ctx) {
+        SimpleType type = new SimpleType(ctx.type.getText());
+        String expected = ctx.expected.getText();
+        Field field = new ReservedField(type, expected);
+        parserContexts.peek().add(field);
+    }
+
+    @Override
+    public void enterTypeSwitchField(ImaginaryParser.TypeSwitchFieldContext ctx) {
+        String discriminator = ctx.discriminator.getText();
+        SwitchField switchField = new SwitchField(discriminator);
+        parserContexts.peek().add(switchField);
+    }
+
+    @Override
+    public void enterCaseStatement(ImaginaryParser.CaseStatementContext ctx) {
+        List<Field> parserContext = new LinkedList<>();
+        parserContexts.push(parserContext);
+    }
+
+    @Override
+    public void exitCaseStatement(ImaginaryParser.CaseStatementContext ctx) {
+        String typeName = ctx.name.getText();
+        int numDiscriminatorValues = (ctx.discriminatorValues.children != null) ?
+            ctx.discriminatorValues.children.size() : 0;
+        String[] discriminatorValues = new String[numDiscriminatorValues];
+        for (int i = 0; i < numDiscriminatorValues; i++) {
+            discriminatorValues[i] = ctx.discriminatorValues.children.get(i).getText();
+        }
+        DiscriminatedComplexType type =
+            new DiscriminatedComplexType(typeName, discriminatorValues, parserContexts.pop());
+
+        // Add the type to the switch field definition.
+        SwitchField switchField = getSwitchField();
+        if(switchField == null) {
+            throw new RuntimeException("This shouldn't have happened");
+        }
+        switchField.addCase(type);
+
+        // Add the type to the type list.
+        complexTypes.put(typeName, type);
+    }
+
+
+    private SwitchField getSwitchField() {
+        for (Field field : parserContexts.peek()) {
+            if(field instanceof SwitchField) {
+                return (SwitchField) field;
+            }
+        }
+        return null;
+    }
+}
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/parser/MessageFormatParser.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/parser/MessageFormatParser.java
new file mode 100644
index 0000000..df88a0a
--- /dev/null
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/parser/MessageFormatParser.java
@@ -0,0 +1,55 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+package org.apache.plc4x.plugins.codegenerator.parser;
+
+import org.antlr.v4.runtime.CharStreams;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.tree.ParseTree;
+import org.antlr.v4.runtime.tree.ParseTreeWalker;
+import org.apache.plc4x.codegenerator.parser.imaginary.ImaginaryLexer;
+import org.apache.plc4x.codegenerator.parser.imaginary.ImaginaryParser;
+import org.apache.plc4x.plugins.codegenerator.model.ComplexType;
+import org.apache.plc4x.plugins.codegenerator.model.Type;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+
+public class MessageFormatParser {
+
+    public List<Type> parse(InputStream source) {
+        try {
+            ImaginaryLexer lexer = new ImaginaryLexer(CharStreams.fromStream(source));
+            CommonTokenStream tokens = new CommonTokenStream(lexer);
+            ImaginaryParser parser = new ImaginaryParser(tokens);
+            ParseTree tree = parser.file();
+            ParseTreeWalker walker = new ParseTreeWalker();
+            MessageFormatListener listener = new MessageFormatListener();
+            walker.walk(listener, tree);
+            Map<String, ComplexType> complexTypes = listener.getComplexTypes();
+            System.out.println(complexTypes);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        return null;
+    }
+
+}
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java b/sandbox/plc4x-maven-plugin/src/test/java/org/apache/plc4x/plugins/codegenerator/parser/ManualMessageFormatParserTest.java
similarity index 67%
copy from sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
copy to sandbox/plc4x-maven-plugin/src/test/java/org/apache/plc4x/plugins/codegenerator/parser/ManualMessageFormatParserTest.java
index 949c181..d045b2f 100644
--- a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/model/Type.java
+++ b/sandbox/plc4x-maven-plugin/src/test/java/org/apache/plc4x/plugins/codegenerator/parser/ManualMessageFormatParserTest.java
@@ -17,18 +17,16 @@
  under the License.
  */
 
-package org.apache.plc4x.plugins.codegenerator.model;
+package org.apache.plc4x.plugins.codegenerator.parser;
 
-public abstract class Type {
+import java.io.InputStream;
 
-    private final String name;
+public class ManualMessageFormatParserTest {
 
-    public Type(String name) {
-        this.name = name;
-    }
-
-    public String getName() {
-        return name;
+    public static void main(String[] args) {
+        InputStream spec = Thread.currentThread().getContextClassLoader().getResourceAsStream("specs/s7.spec");
+        MessageFormatParser parser = new MessageFormatParser();
+        parser.parse(spec);
     }
 
 }
diff --git a/sandbox/plc4x-maven-plugin/src/test/resources/specs/s7.spec b/sandbox/plc4x-maven-plugin/src/test/resources/specs/s7.spec
new file mode 100644
index 0000000..84356dc
--- /dev/null
+++ b/sandbox/plc4x-maven-plugin/src/test/resources/specs/s7.spec
@@ -0,0 +1,205 @@
+////////////////////////////////////////////////////////////////
+// IsoOnTcp/TPKT
+////////////////////////////////////////////////////////////////
+
+[type TPKTPacket
+    [const    uint8  'protocolId' '0x3']
+    [reserved uint8  '0x0']
+    [implicit uint16 'length' 'payload.size + 4']
+    [embedded 'payload' {length: 'length - 4'}]
+]
+
+////////////////////////////////////////////////////////////////
+// COTP
+////////////////////////////////////////////////////////////////
+
+[discriminatedType COTPPacket [length]
+    [implicit uint8 'headerLength' 'this.size - (payload.size + 1)']
+    [discriminator uint8 'tpduCode']
+    [typeSwitch 'tpduCode'
+        ['0xF0' Data
+            [field bit 'eot']
+            [field uint7 'tpduRef']
+        ]
+        ['0xE0' ConnectionRequest
+            [field uint16 'destinationReference']
+            [field uint16 'sourceReference']
+            [field uint8  'protocolClass']
+        ]
+        ['0xD0' ConnectionResponse
+            [field uint16 'destinationReference']
+            [field uint16 'sourceReference']
+            [field uint8  'protocolClass']
+        ]
+        ['0x80' DisconnectRequest
+            [field uint16 'destinationReference']
+            [field uint16 'sourceReference']
+            [field unit8  'protocolClass']
+        ]
+        ['0xC0' DisconnectResponse
+            [field uint16 'destinationReference']
+            [field uint16 'sourceReference']
+        ]
+        ['0x70' TpduError
+            [field uint16 'destinationReference']
+            [field uint8  'rejectCause']
+        ]
+    ]
+    [arrayField COTPParameter 'parameters' length '(headerLength + 1) - cur']
+    [embedded 'payload' {length: 'length - (headerLength + 1)'}]
+]
+
+[discriminatedType COTPParameter
+    [discriminator uint8 'type']
+    [typeSwitch 'type'
+        ['0xC0' TpduSize
+            [field uint8 'tpduSize']
+        ]
+        ['0xC1' CallingTsap
+            [field uint16 'tsapId']
+        ]
+        ['0xC2' CalledTsap
+            [field uint16 'tsapId']
+        ]
+        ['0xC3' Checksum
+            [field uint8 'checksum']
+        ]
+        ['0xE0' DisconnectAdditionalInformation
+            [arrayField uint8 'data' count 'rest']
+        ]
+    ]
+]
+
+////////////////////////////////////////////////////////////////
+// S7
+////////////////////////////////////////////////////////////////
+
+[discriminatedType S7Message
+    [const    uint8  'protocolId' '0x32']
+    [discriminator uint8 'type']
+    [reserved uint16 '0x00']
+    [field    uint16 'tpduReference']
+    [implicit uint16 'parameterLength' 'parameter.size']
+    [implicit uint16 'payloadLength' 'payload.size']
+    [typeSwitch 'type'
+        ['0x01' Request
+            [context 'messageType' 'request']
+        ]
+        ['0x03' Response
+            [context 'messageType' 'response']
+            [field uint8 'errorClass']
+            [field uint8 'errorCode']
+        ]
+        ['0x07' UserData
+            [context 'messageType' 'userData']
+        ]
+    ]
+    [optionalField S7Parameter 'parameter' 'parameterLength > 0' {messageType: messageType}]
+    [optionalField S7Payload 'payload' 'payloadLength > 0' {messageType: messageType, parameter: parameter}]
+]
+
+////////////////////////////////////////////////////////////////
+// Parameters
+
+[discriminatedType S7Parameter [messageType]
+    [discriminator uint8 'type']
+    [typeSwitch 'type,messageType'
+        ['0xF0' SetupCommunication
+            [reserved uint8 '0x0']
+            [field uint16 'maxAmqCaller']
+            [field uint16 'maxAmqCallee']
+            [field uint16 'pduLength']
+        ]
+        ['0x04','request' ReadVarRequest
+            [implicit uint8 'numItems' 'items.count']
+            [arrayField S7VarRequestParameterItem 'items' count 'numItems']
+        ]
+        ['0x04','response' ReadVarResponse
+            [field uint8 'numItems']
+        ]
+        ['0x05','request' WriteVarRequest
+            [implicit uint8 'numItems' 'items.count']
+            [arrayField S7VarRequestParameterItem 'items' count 'numItems']
+        ]
+        ['0x05','response' WriteVarResponse
+            [field uint8 'numItems']
+        ]
+        ['0x00','userData' UserData
+            [implicit uint8 'items.count']
+            [arrayField UserDataItem 'items' count 'numItems']
+        ]
+    ]
+]
+
+[discriminatedType S7VarRequestParameterItem
+    [discriminator uint8 'type']
+    [typeSwitch 'type'
+        ['0x12' Address
+            [implicit uint8 'addressLength' 'address.size']
+            [field S7Address 'address']
+        ]
+    ]
+]
+
+[discriminatedType S7Address
+    [discriminator uint8 'type']
+    [typeSwitch 'type'
+        ['0x10' Any
+            [field uint8  'transportSize']
+            [field uint16 'length']
+            [field uint8  'dbNumber']
+            [field uint8  'area']
+            [reserved uint5]
+            [field uint16 'byteAddress']
+            [field uint3  'bitAddress']
+        ]
+    ]
+]
+
+[discriminatorType UserDataItem
+    [discriminator uint8 'type']
+    [typeSwitch type
+        ['0x12' CPUFunctions
+            [internal      uint8 'parameterLength']
+            [field         uint16 'type']
+            [field         unit8 'subFunctionGroup']
+            [field         uint8 'sequenceNumber']
+            [optionalField uint8 'dataUnitReferenceNumber' 'parameterLength == 8']
+            [optionalField uint8 'lastDataUnit' 'parameterLength == 8']
+            [optionalField uint8 'errorCode' 'parameterLength == 8']
+
+            // TODO: CPUFunctions still need some love ...
+
+        ]
+    ]
+]
+
+////////////////////////////////////////////////////////////////
+// Payloads
+
+[discriminatorType S7Payload [messageType, parameter]
+    [typeSwitch 'parameter.type, messageType'
+        ['0x04','response' ReadVarResponse
+            [arrayField S7VarPayloadDataItem 'items' count 'parameter.numItems']
+        ]
+        ['0x05','request' WriteVarRequest
+            [arrayField S7VarPayloadDataItem 'items' count 'parameter.numItems']
+        ]
+        ['0x05','response' WriteVarResponse
+            [arrayField S7VarPayloadStatusItem 'items' count 'parameter.numItems']
+        ]
+        ['0x00','userData' UserData
+        ]
+    ]
+]
+
+[type S7VarPayloadDataItem
+    [field uint8 'returnCode']
+    [field uint8 'transportSize']
+    [field uint16 'length']
+    [arrayField uint8 'data' count 'length']
+]
+
+[type S7VarPayloadStatusItem
+    [field uint8 'returnCode']
+]
\ No newline at end of file