From 65e8b7d15e0ebf857aabb5cf276c8157567c239f Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Sat, 29 Jul 2017 21:13:32 -0700 Subject: [PATCH] Change matches to store the string they matched. --- src/org/nwapw/abacus/lexing/Lexer.java | 9 +++--- .../nwapw/abacus/lexing/pattern/Match.java | 32 ++++++------------- src/org/nwapw/abacus/tree/TreeBuilder.java | 30 ++++++++--------- 3 files changed, 28 insertions(+), 43 deletions(-) diff --git a/src/org/nwapw/abacus/lexing/Lexer.java b/src/org/nwapw/abacus/lexing/Lexer.java index 5839801..82f5898 100644 --- a/src/org/nwapw/abacus/lexing/Lexer.java +++ b/src/org/nwapw/abacus/lexing/Lexer.java @@ -102,7 +102,7 @@ public class Lexer { if(index < from.length() && node.matches(from.charAt(index))) { node.addOutputsInto(futureSet); } else if(node instanceof EndNode){ - matches.add(new Match<>(startAt, index, ((EndNode) node).getPatternId())); + matches.add(new Match<>(from.substring(startAt, index), ((EndNode) node).getPatternId())); } } @@ -115,7 +115,7 @@ public class Lexer { } matches.sort((a, b) -> compare.compare(a.getType(), b.getType())); if(compare != null) { - matches.sort(Comparator.comparingInt(a -> a.getTo() - a.getFrom())); + matches.sort(Comparator.comparingInt(a -> a.getContent().length())); } return matches.isEmpty() ? null : matches.get(matches.size() - 1); } @@ -132,9 +132,10 @@ public class Lexer { ArrayList> matches = new ArrayList<>(); Match lastMatch = null; while(index < from.length() && (lastMatch = lexOne(from, index, compare)) != null){ - if(lastMatch.getTo() == lastMatch.getFrom()) return null; + int length = lastMatch.getContent().length(); + if(length == 0) return null; matches.add(lastMatch); - index += lastMatch.getTo() - lastMatch.getFrom(); + index += length; } if(lastMatch == null) return null; return matches; diff --git a/src/org/nwapw/abacus/lexing/pattern/Match.java b/src/org/nwapw/abacus/lexing/pattern/Match.java index 15ee33d..49b7ad8 100644 --- a/src/org/nwapw/abacus/lexing/pattern/Match.java +++ b/src/org/nwapw/abacus/lexing/pattern/Match.java @@ -7,13 +7,9 @@ package org.nwapw.abacus.lexing.pattern; public class Match { /** - * The bottom range of the string, inclusive. + * The content of this match. */ - private int from; - /** - * The top range of the string, exclusive. - */ - private int to; + private String content; /** * The pattern type this match matched. */ @@ -21,30 +17,20 @@ public class Match { /** * Creates a new match with the given parameters. - * @param from the bottom range of the string. - * @param to the top range of the string. + * @param content the content of this match. * @param type the type of the match. */ - public Match(int from, int to, T type){ - this.from = from; - this.to = to; + public Match(String content, T type){ + this.content = content; this.type = type; } /** - * Gets the bottom range bound of the string. - * @return the bottom range bound of the string. + * Gets the content of this match. + * @return the content. */ - public int getFrom() { - return from; - } - - /** - * Gets the top range bound of the string. - * @return the top range bound of the string. - */ - public int getTo() { - return to; + public String getContent() { + return content; } /** diff --git a/src/org/nwapw/abacus/tree/TreeBuilder.java b/src/org/nwapw/abacus/tree/TreeBuilder.java index 97800e4..13ac266 100644 --- a/src/org/nwapw/abacus/tree/TreeBuilder.java +++ b/src/org/nwapw/abacus/tree/TreeBuilder.java @@ -91,11 +91,10 @@ public class TreeBuilder { /** * Rearranges tokens into a postfix list, using Shunting Yard. - * @param source the source string. * @param from the tokens to be rearranged. * @return the resulting list of rearranged tokens. */ - public List> intoPostfix(String source, List> from){ + public List> intoPostfix(List> from){ ArrayList> output = new ArrayList<>(); Stack> tokenStack = new Stack<>(); while(!from.isEmpty()){ @@ -104,10 +103,10 @@ public class TreeBuilder { if(matchType == TokenType.NUM) { output.add(match); } else if(matchType == TokenType.FUNCTION) { - output.add(new Match<>(0, 0, TokenType.INTERNAL_FUNCTION_END)); + output.add(new Match<>("" , TokenType.INTERNAL_FUNCTION_END)); tokenStack.push(match); } else if(matchType == TokenType.OP){ - String tokenString = source.substring(match.getFrom(), match.getTo()); + String tokenString = match.getContent(); OperatorType type = typeMap.get(tokenString); int precedence = precedenceMap.get(tokenString); OperatorAssociativity associativity = associativityMap.get(tokenString); @@ -123,7 +122,7 @@ public class TreeBuilder { if(!(otherMatchType == TokenType.OP || otherMatchType == TokenType.FUNCTION)) break; if(otherMatchType == TokenType.OP){ - int otherPrecedence = precedenceMap.get(source.substring(otherMatch.getFrom(), otherMatch.getTo())); + int otherPrecedence = precedenceMap.get(match.getContent()); if(otherPrecedence < precedence || (associativity == OperatorAssociativity.RIGHT && otherPrecedence == precedence)) { break; @@ -155,34 +154,33 @@ public class TreeBuilder { /** * Constructs a tree recursively from a list of tokens. - * @param source the source string. * @param matches the list of tokens from the source string. * @return the construct tree expression. */ - public TreeNode fromStringRecursive(String source, List> matches){ + public TreeNode fromStringRecursive(List> matches){ if(matches.size() == 0) return null; Match match = matches.remove(0); TokenType matchType = match.getType(); if(matchType == TokenType.OP){ - String operator = source.substring(match.getFrom(), match.getTo()); + String operator = match.getContent(); OperatorType type = typeMap.get(operator); if(type == OperatorType.BINARY_INFIX){ - TreeNode right = fromStringRecursive(source, matches); - TreeNode left = fromStringRecursive(source, matches); + TreeNode right = fromStringRecursive(matches); + TreeNode left = fromStringRecursive(matches); if(left == null || right == null) return null; else return new BinaryInfixNode(operator, left, right); } else { - TreeNode applyTo = fromStringRecursive(source, matches); + TreeNode applyTo = fromStringRecursive(matches); if(applyTo == null) return null; else return new UnaryPrefixNode(operator, applyTo); } } else if(matchType == TokenType.NUM){ - return new NumberNode(abacus.numberFromString(source.substring(match.getFrom(), match.getTo()))); + return new NumberNode(abacus.numberFromString(match.getContent())); } else if(matchType == TokenType.FUNCTION){ - String functionName = source.substring(match.getFrom(), match.getTo()); + String functionName = match.getContent(); FunctionNode node = new FunctionNode(functionName); while(!matches.isEmpty() && matches.get(0).getType() != TokenType.INTERNAL_FUNCTION_END){ - TreeNode argument = fromStringRecursive(source, matches); + TreeNode argument = fromStringRecursive(matches); if(argument == null) return null; node.prependChild(argument); } @@ -202,11 +200,11 @@ public class TreeBuilder { List> matches = tokenize(string); if(matches == null) return null; matches.removeIf(m -> m.getType() == TokenType.WHITESPACE); - matches = intoPostfix(string, matches); + matches = intoPostfix(matches); if(matches == null) return null; Collections.reverse(matches); - return fromStringRecursive(string, matches); + return fromStringRecursive(matches); } }