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);
+ }
+
}