From fc0b88d2f30c09dc091f3fa0fb5989513dbdd149 Mon Sep 17 00:00:00 2001
From: Jeffrey Phillips Freeman <jeffrey.freeman@syncleus.com>
Date: Tue, 14 Jul 2015 00:14:01 -0400
Subject: [PATCH] Added the first part to parsing a logic string, extacts all
the tokens (numbers and variables).
---
.../java/com/syncleus/logicparser/Linked.java | 14 ++--
.../syncleus/logicparser/LinkedObject.java | 22 ++---
.../syncleus/logicparser/LinkedString.java | 8 +-
.../{LinkedLogic.java => LinkedSymbol.java} | 6 +-
.../syncleus/logicparser/LinkedToken.java} | 10 +--
.../com/syncleus/logicparser/LogicParser.java | 83 +++++++++++++++++--
.../com/syncleus/logicparser/StringToken.java | 29 +++++++
.../logicparser/{Logic.java => Symbol.java} | 2 +-
.../java/com/syncleus/logicparser/Token.java | 20 +++++
.../logicparser/SymbolParserTest.java | 47 +++++++++++
10 files changed, 202 insertions(+), 39 deletions(-)
rename src/main/java/com/syncleus/logicparser/{LinkedLogic.java => LinkedSymbol.java} (80%)
rename src/{test/java/com/syncleus/logicparser/LogicParserTest.java => main/java/com/syncleus/logicparser/LinkedToken.java} (81%)
create mode 100644 src/main/java/com/syncleus/logicparser/StringToken.java
rename src/main/java/com/syncleus/logicparser/{Logic.java => Symbol.java} (96%)
create mode 100644 src/main/java/com/syncleus/logicparser/Token.java
create mode 100644 src/test/java/com/syncleus/logicparser/SymbolParserTest.java
diff --git a/src/main/java/com/syncleus/logicparser/Linked.java b/src/main/java/com/syncleus/logicparser/Linked.java
index 2591f72..ee813a9 100644
--- a/src/main/java/com/syncleus/logicparser/Linked.java
+++ b/src/main/java/com/syncleus/logicparser/Linked.java
@@ -16,11 +16,11 @@
*/
package com.syncleus.logicparser;
-public interface Linked<B extends Linked<?,?,?>, A extends Linked<?,?,?>, V> extends NestedString {
- B getBefore();
- void setBefore(B before);
- A getAfter();
- void setAfter(A after);
- V getValue();
- void setValue(V value);
+public interface Linked extends NestedString {
+ Linked getBefore();
+ void setBefore(Linked before);
+ Linked getAfter();
+ void setAfter(Linked after);
+ Object getValue();
+ void setValue(Object value);
}
diff --git a/src/main/java/com/syncleus/logicparser/LinkedObject.java b/src/main/java/com/syncleus/logicparser/LinkedObject.java
index fd83d8e..f132ec0 100644
--- a/src/main/java/com/syncleus/logicparser/LinkedObject.java
+++ b/src/main/java/com/syncleus/logicparser/LinkedObject.java
@@ -16,44 +16,44 @@
*/
package com.syncleus.logicparser;
-public abstract class LinkedObject<B extends Linked<?,?,?>, A extends Linked<?,?,?>, V> implements Linked<B,A,V> {
- private B before;
- private A after;
- private V value;
+public abstract class LinkedObject implements Linked {
+ private Linked before;
+ private Linked after;
+ private Object value;
- public LinkedObject(final B before, final A after, final V value) {
+ public LinkedObject(final Linked before, final Linked after, final Object value) {
this.before = before;
this.after = after;
this.value = value;
}
@Override
- public B getBefore() {
+ public Linked getBefore() {
return before;
}
@Override
- public A getAfter() {
+ public Linked getAfter() {
return after;
}
@Override
- public V getValue() {
+ public Object getValue() {
return value;
}
@Override
- public void setBefore(final B before) {
+ public void setBefore(final Linked before) {
this.before = before;
}
@Override
- public void setAfter(final A after) {
+ public void setAfter(final Linked after) {
this.after = after;
}
@Override
- public void setValue(final V value) {
+ public void setValue(final Object value) {
this.value = value;
}
}
diff --git a/src/main/java/com/syncleus/logicparser/LinkedString.java b/src/main/java/com/syncleus/logicparser/LinkedString.java
index 6e04c0d..147dc1f 100644
--- a/src/main/java/com/syncleus/logicparser/LinkedString.java
+++ b/src/main/java/com/syncleus/logicparser/LinkedString.java
@@ -16,18 +16,18 @@
*/
package com.syncleus.logicparser;
-public class LinkedString<B extends Linked<?,?,?>, A extends Linked<?,?,?>> extends LinkedObject<B,A,String> {
- public LinkedString(final B before, final A after, final String value) {
+public class LinkedString extends LinkedObject {
+ public LinkedString(final Linked before, final Linked after, final String value) {
super(before, after, value);
}
@Override
public String toBaseString() {
- return this.getValue();
+ return (String) this.getValue();
}
@Override
public String toString() {
- return this.getValue();
+ return (String) this.getValue();
}
}
diff --git a/src/main/java/com/syncleus/logicparser/LinkedLogic.java b/src/main/java/com/syncleus/logicparser/LinkedSymbol.java
similarity index 80%
rename from src/main/java/com/syncleus/logicparser/LinkedLogic.java
rename to src/main/java/com/syncleus/logicparser/LinkedSymbol.java
index 8771a94..f071ed5 100644
--- a/src/main/java/com/syncleus/logicparser/LinkedLogic.java
+++ b/src/main/java/com/syncleus/logicparser/LinkedSymbol.java
@@ -16,14 +16,14 @@
*/
package com.syncleus.logicparser;
-public class LinkedLogic<B extends Linked<?,?,?>, A extends Linked<?,?,?>, V extends Logic> extends LinkedObject<B,A,V> {
- public LinkedLogic(final B before, final A after, final V value) {
+public abstract class LinkedSymbol extends LinkedObject {
+ public LinkedSymbol(final Linked before, final Linked after, final Object value) {
super(before, after, value);
}
@Override
public String toBaseString() {
- return "";
+ return " ";
}
@Override
diff --git a/src/test/java/com/syncleus/logicparser/LogicParserTest.java b/src/main/java/com/syncleus/logicparser/LinkedToken.java
similarity index 81%
rename from src/test/java/com/syncleus/logicparser/LogicParserTest.java
rename to src/main/java/com/syncleus/logicparser/LinkedToken.java
index 63aa385..7931178 100644
--- a/src/test/java/com/syncleus/logicparser/LogicParserTest.java
+++ b/src/main/java/com/syncleus/logicparser/LinkedToken.java
@@ -16,12 +16,8 @@
*/
package com.syncleus.logicparser;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class LogicParserTest {
- @Test
- public void testNothing() {
- Assert.assertTrue(true);
+public class LinkedToken extends LinkedSymbol {
+ public LinkedToken(Linked before, Linked after, Object value) {
+ super(before, after, value);
}
}
diff --git a/src/main/java/com/syncleus/logicparser/LogicParser.java b/src/main/java/com/syncleus/logicparser/LogicParser.java
index 25a0377..70e8831 100644
--- a/src/main/java/com/syncleus/logicparser/LogicParser.java
+++ b/src/main/java/com/syncleus/logicparser/LogicParser.java
@@ -16,30 +16,101 @@
*/
package com.syncleus.logicparser;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
public class LogicParser {
- private final Linked<Linked<?,?,?>,Linked<?,?,?>,?> head;
+ private final static Pattern TOKEN_PATTERN = Pattern.compile("([a-zA-Z0-9]{1,})");
+ private Linked head;
public LogicParser(final String logicString) {
- this.head = new LinkedString<>(null, null, logicString);
+ this.head = new LinkedString(null, null, removeWhitespace(logicString));
this.parse();
}
+ private static String removeWhitespace(final String input) {
+ return input.replaceAll("\\s+","");
+ }
+
private void parse() {
+ Matcher match = TOKEN_PATTERN.matcher(toBaseString());
+ while(match.find()) {
+ this.extractToken(match.start(), match.end());
+ match = TOKEN_PATTERN.matcher(toBaseString());
+ }
+ }
+
+ private void extractToken(final int start, final int end) {
+ Linked currentLink = this.head;
+ int currentIndex = 0;
+ while(currentLink.toBaseString().length() + currentIndex < start) {
+ currentIndex += currentLink.toBaseString().length();
+ currentLink = currentLink.getAfter();
+ if(currentLink == null)
+ throw new IllegalArgumentException("start argument is out of bounds");
+ }
+
+ if(!(currentLink instanceof LinkedString))
+ throw new IllegalStateException("Current link is not a LinkedString!");
+
+ final String baseString = currentLink.toBaseString();
+ if(baseString.length() < end - currentIndex)
+ throw new IllegalArgumentException("end argument is out of bounds.");
+
+ final int relativeStart = start - currentIndex;
+ final int relativeEnd = end - currentIndex;
+ final String beforeString = (relativeStart == 0 ? null : baseString.substring(0, relativeStart));
+ final String tokenString = baseString.substring(relativeStart, relativeEnd);
+ final String afterString = (relativeEnd == baseString.length() ? null : baseString.substring(relativeEnd, baseString.length()));
+
+ final LinkedToken tokenLink = new LinkedToken(null, null, new StringToken(tokenString));
+ LinkedString afterLink;
+ if( afterString != null) {
+ afterLink = new LinkedString(tokenLink, currentLink.getAfter(), afterString);
+ if( currentLink.getAfter() != null )
+ currentLink.getAfter().setBefore(afterLink);
+ tokenLink.setAfter(afterLink);
+ }
+ else {
+ if( currentLink.getAfter() != null )
+ currentLink.getAfter().setBefore(tokenLink);
+ tokenLink.setAfter(currentLink.getAfter());
+ }
+
+ if(beforeString != null) {
+ currentLink.setAfter(tokenLink);
+ tokenLink.setBefore(currentLink);
+ currentLink.setValue(beforeString);
+ }
+ else {
+ if( currentLink.getBefore() == null ) {
+ tokenLink.setBefore(null);
+ this.head = tokenLink;
+ }
+ else {
+ tokenLink.setBefore(currentLink.getBefore());
+ currentLink.getBefore().setAfter(tokenLink);
+ }
+ }
+ }
+
+ protected Linked getHead() {
+ return head;
}
- private String toBaseString() {
- Linked<?,?,?> currentLink = this.head;
+ protected String toBaseString() {
+ Linked currentLink = this.head;
final StringBuilder baseBuilder = new StringBuilder();
do {
- baseBuilder.append(this.head.toBaseString());
+ baseBuilder.append(currentLink.toBaseString());
currentLink = currentLink.getAfter();
} while(currentLink != null);
return baseBuilder.toString();
}
public String toString() {
- Linked<?,?,?> currentLink = this.head;
+ Linked currentLink = this.head;
final StringBuilder baseBuilder = new StringBuilder();
do {
baseBuilder.append(this.head.toString());
diff --git a/src/main/java/com/syncleus/logicparser/StringToken.java b/src/main/java/com/syncleus/logicparser/StringToken.java
new file mode 100644
index 0000000..344a37a
--- /dev/null
+++ b/src/main/java/com/syncleus/logicparser/StringToken.java
@@ -0,0 +1,29 @@
+/**
+ * Copyright: (c) Syncleus, Inc.
+ *
+ * You may redistribute and modify this source code under the terms and
+ * conditions of the Open Source Community License - Type C version 1.0
+ * or any later version as published by Syncleus, Inc. at www.syncleus.com.
+ * There should be a copy of the license included with this file. If a copy
+ * of the license is not included you are granted no right to distribute or
+ * otherwise use this file except through a legal and valid license. You
+ * should also contact Syncleus, Inc. at the information below if you cannot
+ * find a license:
+ *
+ * Syncleus, Inc.
+ * 2604 South 12th Street
+ * Philadelphia, PA 19148
+ */
+package com.syncleus.logicparser;
+
+public class StringToken implements Token {
+ private final String value;
+
+ public StringToken(String value) {
+ this.value = value;
+ }
+
+ public String toString() {
+ return this.value;
+ }
+}
diff --git a/src/main/java/com/syncleus/logicparser/Logic.java b/src/main/java/com/syncleus/logicparser/Symbol.java
similarity index 96%
rename from src/main/java/com/syncleus/logicparser/Logic.java
rename to src/main/java/com/syncleus/logicparser/Symbol.java
index 196722c..6afe03a 100644
--- a/src/main/java/com/syncleus/logicparser/Logic.java
+++ b/src/main/java/com/syncleus/logicparser/Symbol.java
@@ -16,5 +16,5 @@
*/
package com.syncleus.logicparser;
-public interface Logic {
+public interface Symbol {
}
diff --git a/src/main/java/com/syncleus/logicparser/Token.java b/src/main/java/com/syncleus/logicparser/Token.java
new file mode 100644
index 0000000..b51081a
--- /dev/null
+++ b/src/main/java/com/syncleus/logicparser/Token.java
@@ -0,0 +1,20 @@
+/**
+ * Copyright: (c) Syncleus, Inc.
+ *
+ * You may redistribute and modify this source code under the terms and
+ * conditions of the Open Source Community License - Type C version 1.0
+ * or any later version as published by Syncleus, Inc. at www.syncleus.com.
+ * There should be a copy of the license included with this file. If a copy
+ * of the license is not included you are granted no right to distribute or
+ * otherwise use this file except through a legal and valid license. You
+ * should also contact Syncleus, Inc. at the information below if you cannot
+ * find a license:
+ *
+ * Syncleus, Inc.
+ * 2604 South 12th Street
+ * Philadelphia, PA 19148
+ */
+package com.syncleus.logicparser;
+
+public interface Token extends Symbol {
+}
diff --git a/src/test/java/com/syncleus/logicparser/SymbolParserTest.java b/src/test/java/com/syncleus/logicparser/SymbolParserTest.java
new file mode 100644
index 0000000..baf8e3c
--- /dev/null
+++ b/src/test/java/com/syncleus/logicparser/SymbolParserTest.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright: (c) Syncleus, Inc.
+ *
+ * You may redistribute and modify this source code under the terms and
+ * conditions of the Open Source Community License - Type C version 1.0
+ * or any later version as published by Syncleus, Inc. at www.syncleus.com.
+ * There should be a copy of the license included with this file. If a copy
+ * of the license is not included you are granted no right to distribute or
+ * otherwise use this file except through a legal and valid license. You
+ * should also contact Syncleus, Inc. at the information below if you cannot
+ * find a license:
+ *
+ * Syncleus, Inc.
+ * 2604 South 12th Street
+ * Philadelphia, PA 19148
+ */
+package com.syncleus.logicparser;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class SymbolParserTest {
+ private final static String FULL_LOGIC_STRING = "foo=(you|me|I)&&(bar>foo+20||something=x|you|z)";
+
+ @Test
+ public void testNothing() {
+ final LogicParserTester parser = new LogicParserTester(FULL_LOGIC_STRING);
+ parser.test();
+ }
+
+ private static class LogicParserTester extends LogicParser {
+ public LogicParserTester(final String logicString) {
+ super(logicString);
+ }
+
+ public void test() {
+ System.out.println("the base string: " + this.toBaseString());
+ System.out.println("The head is: " + this.getHead().toString());
+ System.out.println("The head base is: " + this.getHead().toBaseString());
+ System.out.println("Is the heads after null? " + (this.getHead().getAfter() == null));
+ System.out.println("Head after: " + this.getHead().getAfter().toBaseString());
+ }
+ }
+}
--
GitLab