Skip to content

Commit

Permalink
add bootstrap UDFs and fix issue with scoring
Browse files Browse the repository at this point in the history
  • Loading branch information
sanity committed Jan 12, 2012
1 parent 8f31af0 commit 5a94313
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 64 deletions.
38 changes: 36 additions & 2 deletions src/com/lastcalc/SequentialParser.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
package com.lastcalc;

import java.io.Serializable;
import java.io.*;
import java.util.*;
import java.util.logging.Logger;

import com.google.common.collect.*;

import com.google.appengine.api.utils.SystemProperty;
import com.lastcalc.bootstrap.Bootstrap;
import com.lastcalc.engines.*;
import com.lastcalc.parsers.*;
import com.lastcalc.parsers.UserDefinedParserParser.UserDefinedParser;
import com.lastcalc.parsers.amounts.AmountMathOp;

public class SequentialParser implements Serializable {
private static final Logger log = Logger.getLogger(Bootstrap.class.getName());

public static final Set<String> recognizedWords = Sets.newHashSet();
private static RecentFirstParserPickerFactory globalParserPickerFactory;;
public static RecentFirstParserPickerFactory globalParserPickerFactory;
private static final FixedOrderParserPickerFactory priorityParsers = new FixedOrderParserPickerFactory();
static {
final LinkedList<Parser> allParsers = Lists.newLinkedList();
Expand All @@ -26,6 +30,7 @@ public class SequentialParser implements Serializable {
}
}
allParsers.addAll(AmountMathOp.getOps());

globalParserPickerFactory = new RecentFirstParserPickerFactory(allParsers);

// Recompute worksheet
Expand All @@ -34,6 +39,35 @@ public class SequentialParser implements Serializable {
// Next we want to parse any user-defined functions before subsequent
// parsers screw them up
priorityParsers.addParser(new UserDefinedParserParser());

try {
final BufferedReader br = new BufferedReader(new InputStreamReader(
Bootstrap.class.getResourceAsStream("bootstrap.txt")));
final SequentialParser parser = SequentialParser.create();
int lineNo = 1;
while (true) {
String next = br.readLine();
if (next == null) {
break;
}
next = next.trim();
if (next.length() == 0 || next.startsWith("#")) {
continue;
}
final TokenList parsed = parser.parseNext(next);
if (parsed.size() != 1 || !(parsed.get(0) instanceof UserDefinedParser)) {
log.warning("Failed to parse line" + lineNo + " as UserDefinedParserParser (" + next + ")");
} else {
globalParserPickerFactory.addParser((UserDefinedParser) parsed.get(0));
}
lineNo++;
}
br.close();

} catch (final Exception e) {
log.warning("Exception while loading boostrap parsers: " + e);
e.printStackTrace();
}
}

public static SequentialParser create() {
Expand Down
19 changes: 19 additions & 0 deletions src/com/lastcalc/bootstrap/Bootstrap.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.lastcalc.bootstrap;

import java.util.List;
import java.util.logging.Logger;

import com.google.common.collect.Lists;

import com.lastcalc.parsers.UserDefinedParserParser;

public class Bootstrap {

private static final Logger log = Logger.getLogger(Bootstrap.class.getName());

public static List<UserDefinedParserParser> getParsers() {
final List<UserDefinedParserParser> ret = Lists.newLinkedList();

return ret;
}
}
3 changes: 2 additions & 1 deletion src/com/lastcalc/engines/BacktrackingParseEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ public LinkedList<ParseStep> parse(final TokenList input,
}
subContext.timeout = context.timeout / 5;
final Set<ParseStep> exhausted = Sets.newHashSet();
outer: while (System.currentTimeMillis() - startTime < context.timeout && !candidates.first().isMinimal()) {
outer: while (System.currentTimeMillis() - startTime < context.timeout
&& candidates.first().result.output.size() > 1) {
for (final ParseStep candidateStep : candidates) {
if (exhausted.contains(candidateStep)) {
continue;
Expand Down
58 changes: 1 addition & 57 deletions src/com/lastcalc/engines/ParseStep.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
package com.lastcalc.engines;

import java.util.*;
import java.util.Map.Entry;

import com.lastcalc.TokenList;
import com.lastcalc.parsers.*;
import com.lastcalc.parsers.Parser.ParseResult;
import com.lastcalc.parsers.PreParser.*;


public class ParseStep implements Comparable<ParseStep> {
Expand Down Expand Up @@ -61,59 +57,7 @@ else if (hashCode() > other.hashCode())
double cachedScore = Double.MIN_VALUE;

private double getScore() {
if (cachedScore == Double.MIN_VALUE) {
cachedScore = getScore(result.output) + scoreBias;
}
return cachedScore;
}

public static double getScore(final Object output) {
if (output instanceof Iterable) {
double score = 0;
for (final Object o : ((Iterable<Object>) output)) {
score += getScore(o);
}
return score;
} else if (output instanceof String)
return 1;
else if (output instanceof Map) {
final Map<Object, Object> map = (Map<Object, Object>) output;
double score = 0;
for (final Map.Entry<Object, Object> e : map.entrySet()) {
score += getScore(e.getKey()) + getScore(e.getValue());
}
return score;
} else if (output instanceof MapWithTail) {
final MapWithTail mwt = (MapWithTail) output;
return 1 + getScore(mwt.map) + getScore(mwt.tail);
} else if (output instanceof ListWithTail) {
final ListWithTail lwt = (ListWithTail) output;
return 1 + getScore(lwt.list) + getScore(lwt.tail);
} else
return 0;
}

public boolean isMinimal() {
return isMinimal(result.output);
}

private boolean isMinimal(final Object o) {
if (o instanceof Iterable) {
for (final Object r : ((Iterable<Object>) o)) {
if (!isMinimal(r))
return false;
}
return true;
} else if (o instanceof String)
return false;
else if (o instanceof Map) {
for (final Entry<Object, Object> e : ((Map<Object, Object>) o).entrySet()) {
if (!isMinimal(e.getKey()) || !isMinimal(e.getValue()))
return false;
}
} else if (o instanceof ListWithTail)
return false;
return true;
return result.output.size() + scoreBias;
}
}

4 changes: 4 additions & 0 deletions src/com/lastcalc/engines/RecentFirstParserPickerFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public RecentFirstParserPickerFactory(final Iterable<Parser> parsers, final int
}
}

public void addParser(final Parser parser) {
parsers.add(parser);
}

@Override
public void teach(final Iterable<ParseStep> steps) {
final ArrayList<ParseStep> reversed = Lists.newArrayList(steps);
Expand Down
6 changes: 3 additions & 3 deletions src/com/lastcalc/parsers/UserDefinedParserParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import com.google.common.collect.*;

import com.lastcalc.TokenList;
import com.lastcalc.engines.ParseStep;
import com.lastcalc.parsers.PreParser.*;
import com.lastcalc.parsers.PreParser.ListWithTail;
import com.lastcalc.parsers.PreParser.MapWithTail;


public class UserDefinedParserParser extends Parser {
Expand Down Expand Up @@ -234,7 +234,7 @@ public ParseResult parse(final TokenList tokens, final int templatePos, final Pa
final TokenList flattened = PreParser.flatten(resultTL);
return ParseResult.success(
tokens.replaceWithTokenList(templatePos, templatePos + template.size(), flattened),
-ParseStep.getScore(flattened));
-flattened.size());
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion src/com/lastcalc/parsers/amounts/UnitStripper.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public ParseResult parse(final TokenList tokens, final int templatePos) {
return ParseResult.fail();
return ParseResult.success(
tokens.replaceWithTokens(templatePos, templatePos + template.size(),
Amount.valueOf(amount.getEstimatedValue(), Unit.ONE)), 1);
Amount.valueOf(amount.getEstimatedValue(), Unit.ONE)), 2);
}

@Override
Expand Down
1 change: 1 addition & 0 deletions src/com/lastcalc/servlets/WorksheetServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class WorksheetServlet extends HttpServlet {
public void init() throws ServletException {
// Force initialization of SequentialParser static fields
SequentialParser.create();

}

@Override
Expand Down

0 comments on commit 5a94313

Please sign in to comment.