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