package parser;
import grammar.Expression;
import grammar.Expression.Rule;
import java.util.HashMap;
import java.util.Map;
/**
* Memoizes every rule in a nested hash map: one level for positions, and one
* level for rules.
*/
public class NestedMemo implements Memo
{
/*****************************************************************************
* Maps (input position, parsing expression) pairs to ParseData objects.
*/
private final Map<Integer, Map<Expression, ParseData>> memo = new HashMap<>();
/****************************************************************************/
private final Matcher matcher;
/****************************************************************************/
NestedMemo(Matcher matcher)
{
this.matcher = matcher;
}
/****************************************************************************/
@Override public ParseData get(int position, Expression expr)
{
if (!(expr instanceof Rule)) {
return matcher.parse(expr);
}
Map<Expression, ParseData> inner = memo.get(position);
ParseData out = inner != null ? inner.get(expr) : null;
if (out == null) {
out = matcher.parse(expr);
set(out);
}
return out;
}
/*****************************************************************************
* Memoizes the given match data at the given position.
*/
private void set(ParseData data)
{
Map<Expression, ParseData> inner = memo.get(data.begin);
if (inner == null) {
inner = new HashMap<>();
memo.put(data.begin, inner);
}
inner.put(data.expr, data);
}
/****************************************************************************/
@Override public void clear()
{
memo.clear();
}
}