X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2Fjs%2FParser.java;h=0583202e6a3759e24715c629d24aff969114c923;hb=87c3b60d5ad529a02a85aaa184ac98779b967463;hp=4bf273d78d1e1331d19bad76c702ff7a7ee20bd4;hpb=96cc912c45623abf8a8a37d7c1d6103e5fe58bd5;p=org.ibex.core.git diff --git a/src/org/xwt/js/Parser.java b/src/org/xwt/js/Parser.java index 4bf273d..0583202 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,6 +364,21 @@ 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: { if (tok != ASSIGN_ADD && tok != ASSIGN_SUB) b.add(parserLine, GET_PRESERVE); @@ -682,20 +727,57 @@ class Parser extends Lexer implements ByteCodes { int catchJMPDistance = -1; if (peekToken() == CATCH) { catchJMPDistance = b.size - tryInsn; - String exceptionVar; - getToken(); - consume(LP); - consume(NAME); - exceptionVar = string; - consume(RP); - b.add(parserLine, TOPSCOPE); // the exception is on top of the stack; put it to the chosen name - b.add(parserLine, SWAP); - b.add(parserLine, LITERAL,exceptionVar); - b.add(parserLine, SWAP); - b.add(parserLine, PUT); - b.add(parserLine, POP); - b.add(parserLine, POP); - parseStatement(b, null); + while(peekToken() == CATCH) { + String exceptionVar; + getToken(); + consume(LP); + consume(NAME); + exceptionVar = string; + int[] writebacks = new int[] { -1, -1, -1 }; + if (peekToken() != RP) { + // extended XWT catch block: catch(e faultCode "foo.bar.baz") + consume(NAME); + String propName = string; + b.add(parserLine, DUP); + b.add(parserLine, LITERAL, string); + b.add(parserLine, GET); + b.add(parserLine, DUP); + b.add(parserLine, LITERAL, null); + b.add(parserLine, EQ); + b.add(parserLine, JT); + writebacks[0] = b.size - 1; + if (peekToken() == STRING) { + consume(STRING); + b.add(parserLine, DUP); + b.add(parserLine, LITERAL, string); + b.add(parserLine, LT); + b.add(parserLine, JT); + writebacks[1] = b.size - 1; + b.add(parserLine, LITERAL, string + "/"); // (slash is ASCII after dot) + b.add(parserLine, GE); + b.add(parserLine, JT); + writebacks[2] = b.size - 1; + } else { + consume(NUMBER); + b.add(parserLine, LITERAL, number); + b.add(parserLine, EQ); + b.add(parserLine, JF); + writebacks[1] = b.size - 1; + } + } + consume(RP); + // the exception is on top of the stack; put it to the chosen name + b.add(parserLine, TOPSCOPE); + b.add(parserLine, SWAP); + b.add(parserLine, LITERAL,exceptionVar); + b.add(parserLine, SWAP); + b.add(parserLine, PUT); + b.add(parserLine, POP); + b.add(parserLine, POP); + parseStatement(b, null); + b.add(parserLine, LITERAL, null); // so we have something to pop + for(int i=0; i<3; i++) if (writebacks[i] != -1) b.set(i, JS.N(b.size - i)); + } // pop the try and catch markers b.add(parserLine,POP); b.add(parserLine,POP);