X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2Fjs%2FParser.java;h=ee04b7eb484be47d59c1234de5a0072868931c26;hb=772b947b9b23de711953d0a1e33cef5f356c442a;hp=b67b59c9bff43c08c1a02f799d4300b6e1704fbd;hpb=6261c41b2ac9d182d8c3541e8e0e5fd00062fa43;p=org.ibex.core.git diff --git a/src/org/xwt/js/Parser.java b/src/org/xwt/js/Parser.java index b67b59c..ee04b7e 100644 --- a/src/org/xwt/js/Parser.java +++ b/src/org/xwt/js/Parser.java @@ -314,6 +314,36 @@ class Parser extends Lexer implements ByteCodes { continueExpr(b, minPrecedence); } + private Grammar parseGrammar(Grammar g) throws IOException { + int tok = getToken(); + if (g != null) + switch(tok) { + case BITOR: return new Grammar.Alternative(g, parseGrammar(null)); + case ADD: return parseGrammar(new Grammar.Repetition(g, 1, Integer.MAX_VALUE)); + case MUL: return parseGrammar(new Grammar.Repetition(g, 0, Integer.MAX_VALUE)); + case HOOK: return parseGrammar(new Grammar.Repetition(g, 0, 1)); + } + Grammar g0 = null; + switch(tok) { + //case NUMBER: g0 = new Grammar.Literal(number); break; + case NAME: g0 = new Grammar.Reference(string); break; + case STRING: + g0 = new Grammar.Literal(string); + if (peekToken() == DOT) { + String old = string; + consume(DOT); + consume(DOT); + consume(STRING); + if (old.length() != 1 || string.length() != 1) throw pe("literal ranges must be single-char strings"); + g0 = new Grammar.Range(old.charAt(0), string.charAt(0)); + } + break; + case LP: g0 = parseGrammar(null); consume(RP); break; + default: pushBackToken(); return g; + } + if (g == null) return parseGrammar(g0); + return parseGrammar(new Grammar.Juxtaposition(g, g0)); + } /** * Assuming that a complete assignable (lvalue) has just been @@ -334,19 +364,40 @@ class Parser extends Lexer implements ByteCodes { // force the default case tok = -1; switch(tok) { + + case GRAMMAR: { + b.add(parserLine, GET_PRESERVE); + Grammar g = parseGrammar(null); + if (peekToken() == LC) { + g.action = new JSFunction(sourceName, parserLine, null); + parseBlock(g.action); + g.action.add(parserLine, LITERAL, null); // in case we "fall out the bottom", return NULL + g.action.add(parserLine, RETURN); + } + b.add(parserLine, MAKE_GRAMMAR, g); + b.add(parserLine, PUT); + break; + } + case ASSIGN_BITOR: case ASSIGN_BITXOR: case ASSIGN_BITAND: case ASSIGN_LSH: case ASSIGN_RSH: case ASSIGN_URSH: case ASSIGN_MUL: case ASSIGN_DIV: case ASSIGN_MOD: case ASSIGN_ADD: case ASSIGN_SUB: { - b.add(parserLine, GET_PRESERVE); + if (tok != ASSIGN_ADD && tok != ASSIGN_SUB) b.add(parserLine, GET_PRESERVE); + startExpr(b, precedence[tok]); + int size = b.size; if (tok == ASSIGN_ADD || tok == ASSIGN_SUB) { b.add(parserLine, tok); + b.add(parserLine, GET); + b.add(parserLine, SWAP); } + // tok-1 is always s/^ASSIGN_// (0 is BITOR, 1 is ASSIGN_BITOR, etc) b.add(parserLine, tok - 1, tok-1==ADD ? JS.N(2) : null); b.add(parserLine, PUT); b.add(parserLine, SWAP); b.add(parserLine, POP); + if (tok == ASSIGN_ADD || tok == ASSIGN_SUB) b.set(size, tok, JS.N(b.size - size)); break; }