diff --git a/services/src/main/java/edu/msudenver/tsp/services/parser/Node.java b/services/src/main/java/edu/msudenver/tsp/services/parser/Node.java new file mode 100644 index 0000000..2b92dec --- /dev/null +++ b/services/src/main/java/edu/msudenver/tsp/services/parser/Node.java @@ -0,0 +1,43 @@ +package edu.msudenver.tsp.services.parser; + +import lombok.Getter; +import lombok.Setter; + +public class Node +{ + @Getter private final String statement; + @Getter @Setter private Node left; + @Getter @Setter private Node right; + @Getter @Setter private Node center; + @Getter private final Node parent; + @Getter private final int depth; + + public Node(final String statement, final Node parent) + { + this.statement = statement + "\n"; + left = null; + right = null; + center = null; + this.parent = parent; + if(parent != null) + { + depth = parent.depth + 1; + } + else + { + depth = 0; + } + } + + @Override + public String toString() + { + String returnVal = this.depth + ": " + this.statement; + + if(this.left != null) returnVal += "... " + this.left.toString(); + if(this.center != null) returnVal += "... " + this.center.toString(); + if(this.right != null) returnVal += "... " + this.right.toString(); + + return returnVal; + } +} \ No newline at end of file diff --git a/services/src/main/java/edu/msudenver/tsp/services/parser/ParserConfig.java b/services/src/main/java/edu/msudenver/tsp/services/parser/ParserConfig.java deleted file mode 100644 index eb1c4f2..0000000 --- a/services/src/main/java/edu/msudenver/tsp/services/parser/ParserConfig.java +++ /dev/null @@ -1,11 +0,0 @@ -package edu.msudenver.tsp.services.parser; - -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; - -@Configuration -@ComponentScan -//@PropertySource("classpath:development.properties") -public class ParserConfig { - -} diff --git a/services/src/main/java/edu/msudenver/tsp/services/parser/ParserService.java b/services/src/main/java/edu/msudenver/tsp/services/parser/ParserService.java index 747521d..0106b8b 100644 --- a/services/src/main/java/edu/msudenver/tsp/services/parser/ParserService.java +++ b/services/src/main/java/edu/msudenver/tsp/services/parser/ParserService.java @@ -7,12 +7,16 @@ import edu.msudenver.tsp.persistence.controller.TheoremController; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.ArrayList; +import java.util.List; + @Service class ParserService { private final DefinitionController definitionController; private final TheoremController theoremController; private final NotationController notationController; private final ProofController proofController; + private Node root; @Autowired public ParserService(final DefinitionController definitionController, final TheoremController theoremController, @@ -23,4 +27,117 @@ class ParserService { this.proofController = proofController; } + public boolean parseUserInput(final String userInput) + { + try { + final Node tree = parseRawInput(userInput); + final List statements = retrieveStatements(tree); + + return true; + } catch(final Exception e) { + e.printStackTrace(); + } + return false; + } + + public Node parseRawInput(String input) + { + input = input.toLowerCase(); + + root = new Node(input, null); + + if(input.equals("")) + { + return root; + } + + recurse(root); + + return root; + } + + private void recurse(final Node current) + { + int startIndex; + int endIndex; + final String statement; + + if (current != null) { + statement = current.getStatement(); + } else { + return; + } + + String nextStatement; + + if(statement.contains("let")) + { + current.setLeft(new Node("let", current)); + + startIndex = statement.indexOf("let")+"let".length(); + + if(statement.contains("if")){ + endIndex = statement.indexOf("if"); + } else if(statement.contains("then")){ + endIndex = statement.indexOf("then"); + } else { + endIndex = statement.length(); + } + + nextStatement = statement.substring(startIndex, endIndex); + + current.getLeft().setCenter(new Node(nextStatement, current.getLeft())); + recurse(current.getLeft().getCenter()); + } + + + if(statement.contains("if")) + { + current.setCenter(new Node("if", current)); + + startIndex = statement.indexOf("if")+"if".length(); + endIndex = (statement.contains("then") ? statement.indexOf("then") : statement.length()); + nextStatement = statement.substring(startIndex, endIndex); + + current.getCenter().setCenter(new Node(nextStatement, current.getCenter())); + recurse(current.getCenter().getCenter()); + } + + + if(current.getStatement().contains("then")) + { + current.setRight(new Node("then", current)); + + startIndex = statement.indexOf("then")+"then".length(); + nextStatement = statement.substring(startIndex); + + current.getRight().setCenter(new Node(nextStatement, current.getRight())); + recurse(current.getRight().getCenter()); + } + } + + public List retrieveStatements(final Node parsedTree) + { + return populateStatementList(parsedTree, new ArrayList<>()); + } + + private ArrayList populateStatementList(final Node node, final ArrayList statementList) + { + if(node == null) + { + return statementList; + } + + final String statement = node.getStatement().trim(); + if(!(statement.contains("let") || statement.contains("if") || statement.contains("then"))) + { + statementList.add(statement); + } + + populateStatementList(node.getLeft(), statementList); + populateStatementList(node.getCenter(), statementList); + populateStatementList(node.getRight(), statementList); + + return statementList; + } } diff --git a/services/src/test/java/edu/msudenver/tsp/services/parser/ParserServiceTest.java b/services/src/test/java/edu/msudenver/tsp/services/parser/ParserServiceTest.java index 1ae6e5e..829a02a 100644 --- a/services/src/test/java/edu/msudenver/tsp/services/parser/ParserServiceTest.java +++ b/services/src/test/java/edu/msudenver/tsp/services/parser/ParserServiceTest.java @@ -1,17 +1,143 @@ package edu.msudenver.tsp.services.parser; +import edu.msudenver.tsp.persistence.controller.DefinitionController; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.InjectMocks; import org.mockito.runners.MockitoJUnitRunner; +import java.util.ArrayList; +import java.util.List; + import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class ParserServiceTest { + private final DefinitionController definitionControllerMock = mock(DefinitionController.class); + private final ParserService mockParserService = mock(ParserService.class); + + @InjectMocks + private final ParserService parserService = new ParserService(definitionControllerMock, null, + null, null); + @Test - public void test() { - assertEquals(3,3); + public void testEmptyStringEqualsEmptyString() { + final String expected = "0: \n"; + final String actual = parserService.parseRawInput("").toString(); + + assertEquals(expected, actual); } + @Test + public void testUselessStringEqualsUselessString() { + final String expected = "0: cat\n"; + final String actual = parserService.parseRawInput("cat").toString(); + + assertEquals(expected, actual); + } + + @Test + public void testSingleIfReturnsIfPlusEmptyString() { + final String expected = "0: if\n... 1: if\n... 2: \n\n"; + final String actual = parserService.parseRawInput("if").toString(); + + assertEquals(expected, actual); + } + + @Test + public void testBaseCaseIfXIsEvenThenXSquaredIsEven() { + final String expected = "0: if x is even then x^2 is even\n" + + "... 1: if\n" + + "... 2: x is even \n" + + "... 1: then\n" + + "... 2: x^2 is even\n\n"; + + final String actual = parserService.parseRawInput("if x is even then x^2 is even").toString(); + + assertEquals(expected, actual); + } + + @Test + public void testLetXBeEvenThenXSquaredIsEven() { + final String expected = "0: let x be even. then x^2 is even.\n" + + "... 1: let\n" + + "... 2: x be even. \n" + + "... 1: then\n" + + "... 2: x^2 is even.\n\n"; + + final String actual = parserService.parseRawInput("Let x be even. Then x^2 is even.").toString(); + + assertEquals(expected, actual); + } + + @Test + public void testLetIfThen() { + final String expected = "0: let a. if b, then c.\n" + + "... 1: let\n" + + "... 2: a. \n" + + "... 1: if\n" + + "... 2: b, \n" + + "... 1: then\n" + + "... 2: c.\n\n"; + + final String actual = parserService.parseRawInput("Let a. If b, then c.").toString(); + + assertEquals(expected, actual); + } + + @Test + public void testLetStatementWithoutAnyIfOrThenStatements() { + final String expected = "0: let a be equal to b.\n" + + "... 1: let\n" + + "... 2: a be equal to b.\n\n"; + + final String actual = parserService.parseRawInput("Let a be equal to b.").toString(); + + assertEquals(expected, actual); + } + + @Test + public void testEmptyStringReturnsEmptyList() { + final List expectedList = new ArrayList<>(); + expectedList.add(""); + + when(mockParserService.parseRawInput(anyString())).thenReturn(new Node("", null)); + final List actualList = parserService.retrieveStatements(mockParserService.parseRawInput("")); + + assertEquals(expectedList, actualList); + } + + @Test + public void testBaseCaseReturnsXIsEven() { + final List expectedList = new ArrayList<>(); + expectedList.add("x is even"); + expectedList.add("x^2 is even"); + + final Node testNode = new Node("if x is even then x^2 is even", null); + testNode.setCenter(new Node("if", testNode)); + testNode.getCenter().setCenter(new Node(" x is even ", testNode.getCenter())); + testNode.setRight(new Node("then", testNode)); + testNode.getRight().setCenter(new Node(" x^2 is even", testNode.getRight())); + + when(mockParserService.parseRawInput(anyString())).thenReturn(testNode); + final List actualList = parserService.retrieveStatements(mockParserService.parseRawInput("baseCase")); + + assertEquals(expectedList, actualList); + } + + @Test + public void testDriveParseUserInput() { + final Node testNode = new Node("", null); + when(mockParserService.parseRawInput(anyString())).thenReturn(testNode); + when(mockParserService.retrieveStatements(testNode)).thenReturn(new ArrayList<>()); + + final boolean successfulTestDrive = parserService.parseUserInput(""); + + assertTrue(successfulTestDrive); + } } \ No newline at end of file