diff --git a/src/main/java/com/syncleus/logicparser/Linked.java b/src/main/java/com/syncleus/logicparser/Linked.java index 2591f723ab1b902b67919230ceaca965bcbf964c..ee813a9e8258777ce3732fc589c322d1debf2e78 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 fd83d8e8550fa418bb989570a43e6f06054995c6..f132ec02a2845918912fdc9ecbd5e1635f1839b9 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 6e04c0d32108b29bed7cf2d61cd01306a2965da7..147dc1f9ca42d5185b0352b7aadf73e06d8cd618 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 8771a9475edc54b1f9e8e4ad7e65dabc741616f5..f071ed5a9107e053df71821d015074f1b71f30d7 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 63aa38544ac7a85c87a99451a8fc0896e6637fce..79311786808fe05d4253d111ac6f4a37d763fea1 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 25a03771f9a13cef4e981ec49e018812b3b0e9ef..70e88318fb242df8d9b16d1e1659f85eabbb318a 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 0000000000000000000000000000000000000000..344a37ad8fae76b565ff75d4891108ae07949501 --- /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 196722c5541013323027e1277d3c607f5c9c319c..6afe03ae5e47676af06b2ef4a644c56229cff1ec 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 0000000000000000000000000000000000000000..b51081a9560444037ecce7f274e25ca07d70de2f --- /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 0000000000000000000000000000000000000000..baf8e3ce26795678c7cfef420a02c12b863cb351 --- /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()); + } + } +}