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/10/11 17:02:35 UTC

[plc4x] 01/04: - Fixed a problem in parsing expressions with multiple levels of nesting

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

cdutz pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 14c1ed75a97cbca347ef7d4d1e156af3c28ee9b3
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Fri Oct 11 18:59:15 2019 +0200

    - Fixed a problem in parsing expressions with multiple levels of nesting
---
 .../language/mspec/expression/Expression.g4        |  14 ++-
 .../mspec/expression/ExpressionStringListener.java | 101 +++++++++++++++++++--
 .../mspec/expression/ExpressionStringParser.java   |   1 -
 .../mspec/parser/MessageFormatListener.java        |  20 +++-
 4 files changed, 122 insertions(+), 14 deletions(-)

diff --git a/build-utils/protocol-base-mspec/src/main/antlr4/org/apache/plc4x/plugins/codegenerator/language/mspec/expression/Expression.g4 b/build-utils/protocol-base-mspec/src/main/antlr4/org/apache/plc4x/plugins/codegenerator/language/mspec/expression/Expression.g4
index d4f8ef4..00c9f5f 100644
--- a/build-utils/protocol-base-mspec/src/main/antlr4/org/apache/plc4x/plugins/codegenerator/language/mspec/expression/Expression.g4
+++ b/build-utils/protocol-base-mspec/src/main/antlr4/org/apache/plc4x/plugins/codegenerator/language/mspec/expression/Expression.g4
@@ -31,7 +31,19 @@ expression
  ;
 
 identifierSegment
- : name=Identifier args=arguments? index=indexes? ('.' rest=identifierSegment)?
+ : name=Identifier args=identifierSegmentArguments? index=identifierSegmentIndexes? ('.' rest=identifierSegmentRest)?
+ ;
+
+identifierSegmentArguments
+ : arguments
+ ;
+
+identifierSegmentIndexes
+ : indexes
+ ;
+
+identifierSegmentRest
+ : identifierSegment
  ;
 
 arguments
diff --git a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/expression/ExpressionStringListener.java b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/expression/ExpressionStringListener.java
index b8ea9f9..bec1f9d 100644
--- a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/expression/ExpressionStringListener.java
+++ b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/expression/ExpressionStringListener.java
@@ -21,6 +21,7 @@ package org.apache.plc4x.plugins.codegenerator.language.mspec.expression;
 
 import org.apache.plc4x.plugins.codegenerator.types.terms.*;
 
+import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Stack;
@@ -83,14 +84,70 @@ public class ExpressionStringListener extends ExpressionBaseListener {
     }
 
     @Override
-    public void enterIdentifierExpression(ExpressionParser.IdentifierExpressionContext ctx) {
+    public void enterIdentifierSegment(ExpressionParser.IdentifierSegmentContext ctx) {
         parserContexts.push(new LinkedList<>());
     }
 
     @Override
-    public void exitIdentifierExpression(ExpressionParser.IdentifierExpressionContext ctx) {
+    public void exitIdentifierSegment(ExpressionParser.IdentifierSegmentContext ctx) {
         List<Term> args = parserContexts.pop();
-        parserContexts.peek().add(getVariableLiteral(ctx.identifierSegment(), args));
+        ArgsContext argsContext = null;
+        IndexContext indexContext = null;
+        RestContext restContext = null;
+        for (Term arg : args) {
+            if(arg instanceof ArgsContext) {
+                argsContext = (ArgsContext) arg;
+            } else if(arg instanceof IndexContext) {
+                indexContext = (IndexContext) arg;
+            } else if(arg instanceof RestContext) {
+                restContext = (RestContext) arg;
+            }
+        }
+
+        String name = ctx.name.getText();
+
+        int index = VariableLiteral.NO_INDEX;
+        if(indexContext != null) {
+            index = indexContext.getFirst().getNumber().intValue();
+        }
+        VariableLiteral rest = null;
+        if(restContext != null) {
+            rest = restContext.getFirst();
+        }
+        parserContexts.peek().add(new VariableLiteral(name, argsContext, index, rest));
+    }
+
+    @Override
+    public void enterIdentifierSegmentArguments(ExpressionParser.IdentifierSegmentArgumentsContext ctx) {
+        parserContexts.push(new LinkedList<>());
+    }
+
+    @Override
+    public void exitIdentifierSegmentArguments(ExpressionParser.IdentifierSegmentArgumentsContext ctx) {
+        List<Term> args = parserContexts.pop();
+        parserContexts.peek().add(new ArgsContext(args));
+    }
+
+    @Override
+    public void enterIdentifierSegmentIndexes(ExpressionParser.IdentifierSegmentIndexesContext ctx) {
+        parserContexts.push(new LinkedList<>());
+    }
+
+    @Override
+    public void exitIdentifierSegmentIndexes(ExpressionParser.IdentifierSegmentIndexesContext ctx) {
+        List<Term> args = parserContexts.pop();
+        parserContexts.peek().add(new IndexContext(args));
+    }
+
+    @Override
+    public void enterIdentifierSegmentRest(ExpressionParser.IdentifierSegmentRestContext ctx) {
+        parserContexts.push(new LinkedList<>());
+    }
+
+    @Override
+    public void exitIdentifierSegmentRest(ExpressionParser.IdentifierSegmentRestContext ctx) {
+        List<Term> args = parserContexts.pop();
+        parserContexts.peek().add(new RestContext(args));
     }
 
     /////////////////////////////////////////////////////////////////////////////////////////
@@ -230,13 +287,6 @@ public class ExpressionStringListener extends ExpressionBaseListener {
     // Helpers
     /////////////////////////////////////////////////////////////////////////////////////////
 
-    private VariableLiteral getVariableLiteral(ExpressionParser.IdentifierSegmentContext ctx, List<Term> args) {
-        String name = ctx.name.getText();
-        int index = (ctx.index != null) ? Integer.valueOf(ctx.index.getText().substring(1, ctx.index.getText().length() - 1)) : VariableLiteral.NO_INDEX;
-        VariableLiteral child = (ctx.rest != null) ? getVariableLiteral(ctx.rest, args) : null;
-        return new VariableLiteral(name, args, index, child);
-    }
-
     private UnaryTerm getUnaryTerm(String op, List<Term> terms) {
         if(terms.size() != 1) {
             throw new RuntimeException(op + " should be a unary operation");
@@ -264,4 +314,35 @@ public class ExpressionStringListener extends ExpressionBaseListener {
         return new TernaryTerm(a, b, c, op);
     }
 
+    static class ArgsContext extends LinkedList<Term> implements Term {
+        public ArgsContext(Collection c) {
+            super(c);
+        }
+
+        @Override
+        public boolean contains(String str) {
+            return false;
+        }
+    }
+    static class IndexContext extends LinkedList<NumericLiteral> implements Term {
+        public IndexContext(Collection c) {
+            super(c);
+        }
+
+        @Override
+        public boolean contains(String str) {
+            return false;
+        }
+    }
+    static class RestContext extends LinkedList<VariableLiteral> implements Term {
+        public RestContext(Collection c) {
+            super(c);
+        }
+
+        @Override
+        public boolean contains(String str) {
+            return false;
+        }
+    }
+
 }
diff --git a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/expression/ExpressionStringParser.java b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/expression/ExpressionStringParser.java
index 4fccf54..76c131d 100644
--- a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/expression/ExpressionStringParser.java
+++ b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/expression/ExpressionStringParser.java
@@ -30,7 +30,6 @@ import java.io.InputStream;
 
 public class ExpressionStringParser {
 
-
     public Term parse(InputStream source) {
         try {
             ExpressionLexer lexer = new ExpressionLexer(CharStreams.fromStream(source));
diff --git a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java
index 188c6f0..74ff1cf 100644
--- a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java
+++ b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java
@@ -374,7 +374,11 @@ public class MessageFormatListener extends MSpecBaseListener {
     private Term getExpressionTerm(String expressionString) {
         InputStream inputStream = IOUtils.toInputStream(expressionString, Charset.defaultCharset());
         ExpressionStringParser parser = new ExpressionStringParser();
-        return  parser.parse(inputStream);
+        try {
+            return parser.parse(inputStream);
+        } catch (Exception e) {
+            throw new RuntimeException("Error parsing expression: '" + expressionString + "'", e);
+        }
     }
 
     private TypeReference getTypeReference(MSpecParser.TypeReferenceContext ctx) {
@@ -440,7 +444,11 @@ public class MessageFormatListener extends MSpecBaseListener {
     private Term parseExpression(String expressionString) {
         InputStream inputStream = IOUtils.toInputStream(expressionString, Charset.defaultCharset());
         ExpressionStringParser parser = new ExpressionStringParser();
-        return parser.parse(inputStream);
+        try {
+            return parser.parse(inputStream);
+        } catch (Exception e) {
+            throw new RuntimeException("Error parsing expression: '" + expressionString + "'", e);
+        }
     }
 
     private String unquoteString(String quotedString) {
@@ -450,4 +458,12 @@ public class MessageFormatListener extends MSpecBaseListener {
         return quotedString;
     }
 
+    public static void main(String[] args) {
+        //Term term = new ExpressionStringParser().parse(IOUtils.toInputStream("CAST(CAST(parameter,S7ParameterUserData).items(hurz)[0],S7ParameterUserDataItemCPUFunctions).cpuFunctionType", Charset.defaultCharset()));
+        //Term term = new ExpressionStringParser().parse(IOUtils.toInputStream("CAST(parameter,S7ParameterUserData).items(hurz)[0]", Charset.defaultCharset()));
+        Term term = new ExpressionStringParser().parse(IOUtils.toInputStream("payload.lengthInBytes+4", Charset.defaultCharset()));
+
+        System.out.println(term);
+    }
+
 }