package org.textmapper.lapg.ui.settings;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import org.textmapper.lapg.ui.settings.SettingsLexer.ErrorReporter;
import org.textmapper.lapg.ui.settings.SettingsLexer.LapgSymbol;
import org.textmapper.lapg.ui.settings.SettingsLexer.Lexems;
public class SettingsParser {
public static class ParseException extends Exception {
private static final long serialVersionUID = 1L;
public ParseException() {
}
}
private final ErrorReporter reporter;
public SettingsParser(ErrorReporter reporter) {
this.reporter = reporter;
}
private static final boolean DEBUG_SYNTAX = false;
private static final int lapg_action[] = {
-1, -1, -3, 1, -1, 2, -1, -9, -1, -21, 4, -1, -1, 5, 7, -1,
-1, 10, -1, 9, 8, -1, 11, -1, -2
};
private static final short lapg_lalr[] = {
4, -1, 0, 0, -1, -2, 8, -1, 0, 6, 1, 6, 4, 6, 10, 6,
-1, -2, 1, -1, 10, -1, 0, 3, 4, 3, -1, -2
};
private static final short lapg_sym_goto[] = {
0, 1, 4, 9, 9, 11, 12, 13, 14, 16, 17, 19, 20, 21, 23, 24,
26, 27
};
private static final short lapg_sym_from[] = {
23, 6, 8, 9, 1, 11, 15, 16, 21, 0, 2, 4, 11, 18, 7, 12,
18, 6, 9, 0, 0, 0, 2, 6, 6, 9, 15
};
private static final short lapg_sym_to[] = {
24, 7, 12, 7, 4, 14, 17, 19, 22, 1, 1, 6, 15, 20, 11, 16,
21, 8, 8, 23, 2, 3, 5, 9, 10, 13, 18
};
private static final short lapg_rlen[] = {
1, 1, 2, 4, 1, 2, 1, 3, 5, 4, 1, 3
};
private static final short lapg_rlex[] = {
11, 12, 12, 13, 14, 14, 15, 15, 15, 15, 16, 16
};
private static final String[] lapg_syms = new String[] {
"eoi",
"identifier",
"scon",
"_skip",
"'['",
"']'",
"'('",
"')'",
"'='",
"','",
"Ldef",
"input",
"settings_list",
"settings",
"options_list",
"option",
"string_list",
};
public interface Tokens extends Lexems {
// non-terminals
public static final int input = 11;
public static final int settings_list = 12;
public static final int settings = 13;
public static final int options_list = 14;
public static final int option = 15;
public static final int string_list = 16;
}
private static int lapg_next(int state, int symbol) {
int p;
if (lapg_action[state] < -2) {
for (p = -lapg_action[state] - 3; lapg_lalr[p] >= 0; p += 2) {
if (lapg_lalr[p] == symbol) {
break;
}
}
return lapg_lalr[p + 1];
}
return lapg_action[state];
}
private static int lapg_state_sym(int state, int symbol) {
int min = lapg_sym_goto[symbol], max = lapg_sym_goto[symbol + 1] - 1;
int i, e;
while (min <= max) {
e = (min + max) >> 1;
i = lapg_sym_from[e];
if (i == state) {
return lapg_sym_to[e];
} else if (i < state) {
min = e + 1;
} else {
max = e - 1;
}
}
return -1;
}
private int lapg_head;
private LapgSymbol[] lapg_m;
private LapgSymbol lapg_n;
public AstInput parse(SettingsLexer lexer) throws IOException, ParseException {
lapg_m = new LapgSymbol[1024];
lapg_head = 0;
lapg_m[0] = new LapgSymbol();
lapg_m[0].state = 0;
lapg_n = lexer.next();
while (lapg_m[lapg_head].state != 24) {
int lapg_i = lapg_next(lapg_m[lapg_head].state, lapg_n.lexem);
if (lapg_i >= 0) {
reduce(lapg_i);
} else if (lapg_i == -1) {
shift(lexer);
}
if (lapg_i == -2 || lapg_m[lapg_head].state == -1) {
break;
}
}
if (lapg_m[lapg_head].state != 24) {
reporter.error(lapg_n.offset, lapg_n.endoffset, lexer.getTokenLine(), MessageFormat.format("syntax error before line {0}", lexer.getTokenLine()));
throw new ParseException();
}
return (AstInput)lapg_m[lapg_head - 1].sym;
}
private void shift(SettingsLexer lexer) throws IOException {
lapg_m[++lapg_head] = lapg_n;
lapg_m[lapg_head].state = lapg_state_sym(lapg_m[lapg_head - 1].state, lapg_n.lexem);
if (DEBUG_SYNTAX) {
System.out.println(MessageFormat.format("shift: {0} ({1})", lapg_syms[lapg_n.lexem], lexer.current()));
}
if (lapg_m[lapg_head].state != -1 && lapg_n.lexem != 0) {
lapg_n = lexer.next();
}
}
@SuppressWarnings("unchecked")
private void reduce(int rule) {
LapgSymbol lapg_gg = new LapgSymbol();
lapg_gg.sym = (lapg_rlen[rule] != 0) ? lapg_m[lapg_head + 1 - lapg_rlen[rule]].sym : null;
lapg_gg.lexem = lapg_rlex[rule];
lapg_gg.state = 0;
if (DEBUG_SYNTAX) {
System.out.println("reduce to " + lapg_syms[lapg_rlex[rule]]);
}
LapgSymbol startsym = (lapg_rlen[rule] != 0) ? lapg_m[lapg_head + 1 - lapg_rlen[rule]] : lapg_n;
lapg_gg.offset = startsym.offset;
lapg_gg.endoffset = (lapg_rlen[rule] != 0) ? lapg_m[lapg_head].endoffset : lapg_n.offset;
switch (rule) {
case 0: // input ::= settings_list
lapg_gg.sym = new AstInput(
((List<AstSettings>)lapg_m[lapg_head-0].sym) /* settingsList */,
null /* input */, lapg_m[lapg_head-0].offset, lapg_m[lapg_head-0].endoffset);
break;
case 1: // settings_list ::= settings
lapg_gg.sym = new ArrayList();
((List<AstSettings>)lapg_gg.sym).add(((AstSettings)lapg_m[lapg_head-0].sym));
break;
case 2: // settings_list ::= settings_list settings
((List<AstSettings>)lapg_m[lapg_head-1].sym).add(((AstSettings)lapg_m[lapg_head-0].sym));
break;
case 3: // settings ::= '[' scon ']' options_list
lapg_gg.sym = new AstSettings(
((String)lapg_m[lapg_head-2].sym) /* scon */,
((List<AstOption>)lapg_m[lapg_head-0].sym) /* optionsList */,
null /* input */, lapg_m[lapg_head-3].offset, lapg_m[lapg_head-0].endoffset);
break;
case 4: // options_list ::= option
lapg_gg.sym = new ArrayList();
((List<AstOption>)lapg_gg.sym).add(((AstOption)lapg_m[lapg_head-0].sym));
break;
case 5: // options_list ::= options_list option
((List<AstOption>)lapg_m[lapg_head-1].sym).add(((AstOption)lapg_m[lapg_head-0].sym));
break;
case 6: // option ::= identifier
lapg_gg.sym = new AstOption(
false,
((String)lapg_m[lapg_head-0].sym) /* identifier */,
null /* scon */,
null /* stringList */,
null /* input */, lapg_m[lapg_head-0].offset, lapg_m[lapg_head-0].endoffset);
break;
case 7: // option ::= identifier '=' scon
lapg_gg.sym = new AstOption(
false,
((String)lapg_m[lapg_head-2].sym) /* identifier */,
((String)lapg_m[lapg_head-0].sym) /* scon */,
null /* stringList */,
null /* input */, lapg_m[lapg_head-2].offset, lapg_m[lapg_head-0].endoffset);
break;
case 8: // option ::= identifier '=' '(' string_list ')'
lapg_gg.sym = new AstOption(
false,
((String)lapg_m[lapg_head-4].sym) /* identifier */,
null /* scon */,
((List<String>)lapg_m[lapg_head-1].sym) /* stringList */,
null /* input */, lapg_m[lapg_head-4].offset, lapg_m[lapg_head-0].endoffset);
break;
case 9: // option ::= Ldef identifier '=' scon
lapg_gg.sym = new AstOption(
true,
((String)lapg_m[lapg_head-2].sym) /* identifier */,
((String)lapg_m[lapg_head-0].sym) /* scon */,
null /* stringList */,
null /* input */, lapg_m[lapg_head-3].offset, lapg_m[lapg_head-0].endoffset);
break;
case 10: // string_list ::= scon
lapg_gg.sym = new ArrayList();
((List<String>)lapg_gg.sym).add(((String)lapg_m[lapg_head-0].sym));
break;
case 11: // string_list ::= string_list ',' scon
((List<String>)lapg_m[lapg_head-2].sym).add(((String)lapg_m[lapg_head-0].sym));
break;
}
for (int e = lapg_rlen[rule]; e > 0; e--) {
lapg_m[lapg_head--] = null;
}
lapg_m[++lapg_head] = lapg_gg;
lapg_m[lapg_head].state = lapg_state_sym(lapg_m[lapg_head-1].state, lapg_gg.lexem);
}
}