Mercurial Hosting > luan
diff src/luan/interp/LuanParser.java @ 129:486a0641bca4
add pickle client/server;
fix parser bugs;
git-svn-id: https://luan-java.googlecode.com/svn/trunk@130 21e917c8-12df-6dd8-5cb6-c86387c605b9
author | fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9> |
---|---|
date | Mon, 09 Jun 2014 09:16:16 +0000 |
parents | f0a4abe58593 |
children | 573ce091ae00 |
line wrap: on
line diff
--- a/src/luan/interp/LuanParser.java Sun Jun 08 03:38:25 2014 +0000 +++ b/src/luan/interp/LuanParser.java Mon Jun 09 09:16:16 2014 +0000 @@ -72,6 +72,26 @@ } } + private static class In { + static final In NOTHING = new In(false,false); + + final boolean parens; + final boolean jsp; + + private In(boolean parens,boolean jsp) { + this.parens = parens; + this.jsp = jsp; + } + + In parens() { + return parens ? this : new In(true,jsp); + } + + In jsp() { + return jsp ? this : new In(parens,true); + } + } + private static final String _ENV = "_ENV"; private static final UpValue.Getter[] NO_UP_VALUE_GETTERS = new UpValue.Getter[0]; @@ -161,9 +181,9 @@ } FnDef Expressions() throws ParseException { - Spaces(); + Spaces(In.NOTHING); int start = parser.begin(); - Expressions exprs = ExpList(); + Expressions exprs = ExpList(In.NOTHING); if( exprs != null && parser.endOfInput() ) { Stmt stmt = new ReturnStmt( se(start), exprs ); return parser.success(newFnDef(start,stmt)); @@ -172,7 +192,7 @@ } FnDef RequiredModule() throws ParseException { - Spaces(); + Spaces(In.NOTHING); int start = parser.begin(); frame.isVarArg = true; Stmt stmt = RequiredBlock(); @@ -186,7 +206,7 @@ int stackStart = symbolsSize(); Stmt(stmts); while( StmtSep(stmts) ) { - Spaces(); + Spaces(In.NOTHING); Stmt(stmts); } int stackEnd = symbolsSize(); @@ -235,19 +255,22 @@ } } - private Expressions JspExpressions() throws ParseException { + private Expressions JspExpressions(In in) throws ParseException { + if( in.jsp ) + return null; int start = parser.begin(); if( !parser.match( "%>" ) ) return parser.failure(null); EndOfLine(); + In inJsp = in.jsp(); ExpList.Builder builder = new ExpList.Builder(); while(true) { if( parser.match( "<%=" ) ) { - Spaces(); - builder.add( RequiredExpr() ); + Spaces(inJsp); + builder.add( RequiredExpr(inJsp) ); RequiredMatch( "%>" ); } else if( parser.match( "<%" ) ) { - Spaces(); + Spaces(inJsp); return parser.success(builder.build()); } else { int i = parser.currentIndex(); @@ -265,9 +288,9 @@ private Stmt ReturnStmt() throws ParseException { int start = parser.begin(); - if( !Keyword("return") ) + if( !Keyword("return",In.NOTHING) ) return parser.failure(null); - Expressions exprs = ExpList(); + Expressions exprs = ExpList(In.NOTHING); if( exprs==null ) exprs = ExpList.emptyExpList; return parser.success( new ReturnStmt(se(start),exprs) ); @@ -275,37 +298,37 @@ private Stmt FunctionStmt() throws ParseException { parser.begin(); - if( !Keyword("function") ) + if( !Keyword("function",In.NOTHING) ) return parser.failure(null); int start = parser.currentIndex(); - Var var = nameVar(start,RequiredName()); + Var var = nameVar(start,RequiredName(In.NOTHING)); while( parser.match( '.' ) ) { - Spaces(); - var = indexVar( start, expr(var.expr()), NameExpr(false) ); + Spaces(In.NOTHING); + var = indexVar( start, expr(var.expr()), NameExpr(In.NOTHING) ); } Settable fnName = var.settable(); - FnDef fnDef = RequiredFunction(false); + FnDef fnDef = RequiredFunction(In.NOTHING); return parser.success( new SetStmt(fnName,fnDef) ); } private Stmt LocalFunctionStmt() throws ParseException { parser.begin(); - if( !(Keyword("local") && Keyword("function")) ) + if( !(Keyword("local",In.NOTHING) && Keyword("function",In.NOTHING)) ) return parser.failure(null); - String name = RequiredName(); + String name = RequiredName(In.NOTHING); addSymbol( name ); - FnDef fnDef = RequiredFunction(false); + FnDef fnDef = RequiredFunction(In.NOTHING); return parser.success( new SetStmt( new SetLocalVar(symbolsSize()-1), fnDef ) ); } private Stmt ImportStmt() throws ParseException { int start = parser.begin(); - if( !Keyword("import") ) + if( !Keyword("import",In.NOTHING) ) return parser.failure(null); Expr importExpr = (Expr)nameVar(start,"require").expr(); - String modName = StringLiteral(false); + String modName = StringLiteral(In.NOTHING); if( modName==null ) return parser.failure(null); String varName = modName.substring(modName.lastIndexOf('.')+1); @@ -323,7 +346,7 @@ private Stmt BreakStmt() throws ParseException { parser.begin(); - if( !Keyword("break") ) + if( !Keyword("break",In.NOTHING) ) return parser.failure(null); if( frame.loops <= 0 ) throw parser.exception("'break' outside of loop"); @@ -333,16 +356,16 @@ private Stmt ForStmt() throws ParseException { int start = parser.begin(); int stackStart = symbolsSize(); - if( !Keyword("for") ) + if( !Keyword("for",In.NOTHING) ) return parser.failure(null); - List<String> names = RequiredNameList(false); - if( !Keyword("in") ) + List<String> names = RequiredNameList(In.NOTHING); + if( !Keyword("in",In.NOTHING) ) return parser.failure(null); - Expr expr = expr(RequiredExpr()); - RequiredKeyword("do"); + Expr expr = expr(RequiredExpr(In.NOTHING)); + RequiredKeyword("do",In.NOTHING); addSymbols(names); Stmt loop = RequiredLoopBlock(); - RequiredKeyword("end"); + RequiredKeyword("end",In.NOTHING); Stmt stmt = new ForStmt( se(start), stackStart, symbolsSize() - stackStart, expr, loop ); popSymbols( symbolsSize() - stackStart ); return parser.success(stmt); @@ -350,15 +373,15 @@ private Stmt TryStmt() throws ParseException { parser.begin(); - if( !Keyword("try") ) + if( !Keyword("try",In.NOTHING) ) return parser.failure(null); Stmt tryBlock = RequiredBlock(); - RequiredKeyword("catch"); - String name = RequiredName(); + RequiredKeyword("catch",In.NOTHING); + String name = RequiredName(In.NOTHING); addSymbol(name); - RequiredKeyword("do"); + RequiredKeyword("do",In.NOTHING); Stmt catchBlock = RequiredBlock(); - RequiredKeyword("end"); + RequiredKeyword("end",In.NOTHING); Stmt stmt = new TryStmt( tryBlock, symbolsSize()-1, catchBlock ); popSymbols(1); return parser.success(stmt); @@ -366,23 +389,23 @@ private Stmt DoStmt() throws ParseException { parser.begin(); - if( !Keyword("do") ) + if( !Keyword("do",In.NOTHING) ) return parser.failure(null); Stmt stmt = RequiredBlock(); - RequiredKeyword("end"); + RequiredKeyword("end",In.NOTHING); return parser.success(stmt); } private boolean LocalStmt(List<Stmt> stmts) throws ParseException { parser.begin(); - if( !Keyword("local") ) + if( !Keyword("local",In.NOTHING) ) return parser.failure(); - List<String> names = NameList(false); + List<String> names = NameList(In.NOTHING); if( names==null ) return parser.failure(); if( parser.match( '=' ) ) { - Spaces(); - Expressions values = ExpList(); + Spaces(In.NOTHING); + Expressions values = ExpList(In.NOTHING); if( values==null ) throw parser.exception("Expressions expected"); SetLocalVar[] vars = new SetLocalVar[names.size()]; @@ -396,45 +419,45 @@ return parser.success(); } - private List<String> RequiredNameList(boolean inParens) throws ParseException { + private List<String> RequiredNameList(In in) throws ParseException { parser.begin(); - List<String> names = NameList(inParens); + List<String> names = NameList(in); if( names==null ) parser.exception("Name expected"); return parser.success(names); } - private List<String> NameList(boolean inParens) throws ParseException { - String name = Name(inParens); + private List<String> NameList(In in) throws ParseException { + String name = Name(in); if( name==null ) return null; List<String> names = new ArrayList<String>(); names.add(name); while( parser.match( ',' ) ) { - Spaces(inParens); - names.add( RequiredName() ); + Spaces(in); + names.add( RequiredName(in) ); } return names; } private Stmt WhileStmt() throws ParseException { parser.begin(); - if( !Keyword("while") ) + if( !Keyword("while",In.NOTHING) ) return parser.failure(null); - Expr cnd = expr(RequiredExpr()); - RequiredKeyword("do"); + Expr cnd = expr(RequiredExpr(In.NOTHING)); + RequiredKeyword("do",In.NOTHING); Stmt loop = RequiredLoopBlock(); - RequiredKeyword("end"); + RequiredKeyword("end",In.NOTHING); return parser.success( new WhileStmt(cnd,loop) ); } private Stmt RepeatStmt() throws ParseException { parser.begin(); - if( !Keyword("repeat") ) + if( !Keyword("repeat",In.NOTHING) ) return parser.failure(null); Stmt loop = RequiredLoopBlock(); - RequiredKeyword("until"); - Expr cnd = expr(RequiredExpr()); + RequiredKeyword("until",In.NOTHING); + Expr cnd = expr(RequiredExpr(In.NOTHING)); return parser.success( new RepeatStmt(loop,cnd) ); } @@ -447,21 +470,21 @@ private Stmt IfStmt() throws ParseException { parser.begin(); - if( !Keyword("if") ) + if( !Keyword("if",In.NOTHING) ) return parser.failure(null); return parser.success( IfStmt2() ); } private Stmt IfStmt2() throws ParseException { - Expr cnd = expr(RequiredExpr()); - RequiredKeyword("then"); + Expr cnd = expr(RequiredExpr(In.NOTHING)); + RequiredKeyword("then",In.NOTHING); Stmt thenBlock = RequiredBlock(); Stmt elseBlock; - if( Keyword("elseif") ) { + if( Keyword("elseif",In.NOTHING) ) { elseBlock = IfStmt2(); } else { - elseBlock = Keyword("else") ? RequiredBlock() : Stmt.EMPTY; - RequiredKeyword("end"); + elseBlock = Keyword("else",In.NOTHING) ? RequiredBlock() : Stmt.EMPTY; + RequiredKeyword("end",In.NOTHING); } return new IfStmt(cnd,thenBlock,elseBlock); } @@ -474,7 +497,7 @@ return parser.failure(null); vars.add(s); while( parser.match( ',' ) ) { - Spaces(); + Spaces(In.NOTHING); s = SettableVar(); if( s == null ) return parser.failure(null); @@ -482,8 +505,8 @@ } if( !parser.match( '=' ) ) return parser.failure(null); - Spaces(); - Expressions values = ExpList(); + Spaces(In.NOTHING); + Expressions values = ExpList(In.NOTHING); if( values==null ) throw parser.exception("Expressions expected"); return parser.success( new SetStmt( vars.toArray(new Settable[0]), values ) ); @@ -491,7 +514,7 @@ private Stmt ExpressionsStmt() throws ParseException { parser.begin(); - Expressions exprs = ExpList(); + Expressions exprs = ExpList(In.NOTHING); if( exprs==null ) return parser.failure(null); return parser.success( new ExpressionsStmt(exprs) ); @@ -499,112 +522,104 @@ private Settable SettableVar() throws ParseException { int start = parser.begin(); - Var var = VarZ(false); + Var var = VarZ(In.NOTHING); if( var==null ) return null; return var.settable(); } - private Code RequiredExpr() throws ParseException { - return RequiredExpr(false); - } - - private Code Expr() throws ParseException { - return Expr(false); + private Code RequiredExpr(In in) throws ParseException { + parser.begin(); + return parser.success(required(Expr(in),"Bad expression")); } - private Code RequiredExpr(boolean inParens) throws ParseException { - parser.begin(); - return parser.success(required(Expr(inParens),"Bad expression")); - } - - private Code Expr(boolean inParens) throws ParseException { + private Code Expr(In in) throws ParseException { parser.begin(); Code exp; - return (exp = VarArgs(inParens)) != null - || (exp = JspExpressions()) != null - || (exp = OrExpr(inParens)) != null + return (exp = VarArgs(in)) != null + || (exp = JspExpressions(in)) != null + || (exp = OrExpr(in)) != null ? parser.success(exp) : parser.failure((Code)null) ; } - private Code OrExpr(boolean inParens) throws ParseException { + private Code OrExpr(In in) throws ParseException { int start = parser.begin(); - Code exp = AndExpr(inParens); + Code exp = AndExpr(in); if( exp==null ) return parser.failure(null); - while( Keyword("or",inParens) ) { - exp = new OrExpr( se(start), expr(exp), required(expr(AndExpr(inParens))) ); + while( Keyword("or",in) ) { + exp = new OrExpr( se(start), expr(exp), required(expr(AndExpr(in))) ); } return parser.success(exp); } - private Code AndExpr(boolean inParens) throws ParseException { + private Code AndExpr(In in) throws ParseException { int start = parser.begin(); - Code exp = RelExpr(inParens); + Code exp = RelExpr(in); if( exp==null ) return parser.failure(null); - while( Keyword("and",inParens) ) { - exp = new AndExpr( se(start), expr(exp), required(expr(RelExpr(inParens))) ); + while( Keyword("and",in) ) { + exp = new AndExpr( se(start), expr(exp), required(expr(RelExpr(in))) ); } return parser.success(exp); } - private Code RelExpr(boolean inParens) throws ParseException { + private Code RelExpr(In in) throws ParseException { int start = parser.begin(); - Code exp = ConcatExpr(inParens); + Code exp = ConcatExpr(in); if( exp==null ) return parser.failure(null); while(true) { if( parser.match("==") ) { - Spaces(inParens); - exp = new EqExpr( se(start), expr(exp), required(expr(ConcatExpr(inParens))) ); + Spaces(in); + exp = new EqExpr( se(start), expr(exp), required(expr(ConcatExpr(in))) ); } else if( parser.match("~=") ) { - Spaces(inParens); - exp = new NotExpr( se(start), new EqExpr( se(start), expr(exp), required(expr(ConcatExpr(inParens))) ) ); + Spaces(in); + exp = new NotExpr( se(start), new EqExpr( se(start), expr(exp), required(expr(ConcatExpr(in))) ) ); } else if( parser.match("<=") ) { - Spaces(inParens); - exp = new LeExpr( se(start), expr(exp), required(expr(ConcatExpr(inParens))) ); + Spaces(in); + exp = new LeExpr( se(start), expr(exp), required(expr(ConcatExpr(in))) ); } else if( parser.match(">=") ) { - Spaces(inParens); - exp = new LeExpr( se(start), required(expr(ConcatExpr(inParens))), expr(exp) ); + Spaces(in); + exp = new LeExpr( se(start), required(expr(ConcatExpr(in))), expr(exp) ); } else if( parser.match("<") ) { - Spaces(inParens); - exp = new LtExpr( se(start), expr(exp), required(expr(ConcatExpr(inParens))) ); + Spaces(in); + exp = new LtExpr( se(start), expr(exp), required(expr(ConcatExpr(in))) ); } else if( parser.match(">") ) { - Spaces(inParens); - exp = new LtExpr( se(start), required(expr(ConcatExpr(inParens))), expr(exp) ); + Spaces(in); + exp = new LtExpr( se(start), required(expr(ConcatExpr(in))), expr(exp) ); } else break; } return parser.success(exp); } - private Code ConcatExpr(boolean inParens) throws ParseException { + private Code ConcatExpr(In in) throws ParseException { int start = parser.begin(); - Code exp = SumExpr(inParens); + Code exp = SumExpr(in); if( exp==null ) return parser.failure(null); if( parser.match("..") ) { - Spaces(inParens); - exp = new ConcatExpr( se(start), expr(exp), required(expr(ConcatExpr(inParens))) ); + Spaces(in); + exp = new ConcatExpr( se(start), expr(exp), required(expr(ConcatExpr(in))) ); } return parser.success(exp); } - private Code SumExpr(boolean inParens) throws ParseException { + private Code SumExpr(In in) throws ParseException { int start = parser.begin(); - Code exp = TermExpr(inParens); + Code exp = TermExpr(in); if( exp==null ) return parser.failure(null); while(true) { if( parser.match('+') ) { - Spaces(inParens); - exp = new AddExpr( se(start), expr(exp), required(expr(TermExpr(inParens))) ); + Spaces(in); + exp = new AddExpr( se(start), expr(exp), required(expr(TermExpr(in))) ); } else if( Minus() ) { - Spaces(inParens); - exp = new SubExpr( se(start), expr(exp), required(expr(TermExpr(inParens))) ); + Spaces(in); + exp = new SubExpr( se(start), expr(exp), required(expr(TermExpr(in))) ); } else break; } @@ -616,21 +631,21 @@ return parser.match('-') && !parser.match('-') ? parser.success() : parser.failure(); } - private Code TermExpr(boolean inParens) throws ParseException { + private Code TermExpr(In in) throws ParseException { int start = parser.begin(); - Code exp = UnaryExpr(inParens); + Code exp = UnaryExpr(in); if( exp==null ) return parser.failure(null); while(true) { if( parser.match('*') ) { - Spaces(inParens); - exp = new MulExpr( se(start), expr(exp), required(expr(UnaryExpr(inParens))) ); + Spaces(in); + exp = new MulExpr( se(start), expr(exp), required(expr(UnaryExpr(in))) ); } else if( parser.match('/') ) { - Spaces(inParens); - exp = new DivExpr( se(start), expr(exp), required(expr(UnaryExpr(inParens))) ); + Spaces(in); + exp = new DivExpr( se(start), expr(exp), required(expr(UnaryExpr(in))) ); } else if( Mod() ) { - Spaces(inParens); - exp = new ModExpr( se(start), expr(exp), required(expr(UnaryExpr(inParens))) ); + Spaces(in); + exp = new ModExpr( se(start), expr(exp), required(expr(UnaryExpr(in))) ); } else break; } @@ -642,128 +657,130 @@ return parser.match('%') && !parser.match('>') ? parser.success() : parser.failure(); } - private Code UnaryExpr(boolean inParens) throws ParseException { + private Code UnaryExpr(In in) throws ParseException { int start = parser.begin(); if( parser.match('#') ) { - Spaces(inParens); - return parser.success( new LenExpr( se(start), required(expr(UnaryExpr(inParens))) ) ); + Spaces(in); + return parser.success( new LenExpr( se(start), required(expr(UnaryExpr(in))) ) ); } if( Minus() ) { - Spaces(inParens); - return parser.success( new UnmExpr( se(start), required(expr(UnaryExpr(inParens))) ) ); + Spaces(in); + return parser.success( new UnmExpr( se(start), required(expr(UnaryExpr(in))) ) ); } - if( Keyword("not",inParens) ) { - Spaces(inParens); - return parser.success( new NotExpr( se(start), required(expr(UnaryExpr(inParens))) ) ); + if( Keyword("not",in) ) { + Spaces(in); + return parser.success( new NotExpr( se(start), required(expr(UnaryExpr(in))) ) ); } - Code exp = PowExpr(inParens); + Code exp = PowExpr(in); if( exp==null ) return parser.failure(null); return parser.success(exp); } - private Code PowExpr(boolean inParens) throws ParseException { + private Code PowExpr(In in) throws ParseException { int start = parser.begin(); - Code exp = SingleExpr(inParens); + Code exp = SingleExpr(in); if( exp==null ) return parser.failure(null); if( parser.match('^') ) { - Spaces(inParens); - exp = new ConcatExpr( se(start), expr(exp), required(expr(PowExpr(inParens))) ); + Spaces(in); + exp = new ConcatExpr( se(start), expr(exp), required(expr(PowExpr(in))) ); } return parser.success(exp); } - private Code SingleExpr(boolean inParens) throws ParseException { + private Code SingleExpr(In in) throws ParseException { parser.begin(); Code exp; - exp = FunctionExpr(inParens); + exp = FunctionExpr(in); if( exp != null ) return parser.success(exp); - exp = TableExpr(inParens); + exp = TableExpr(in); if( exp != null ) return parser.success(exp); - exp = VarExp(inParens); + exp = VarExp(in); if( exp != null ) return parser.success(exp); - exp = Literal(inParens); + exp = Literal(in); if( exp != null ) return parser.success(exp); return parser.failure(null); } - private Expr FunctionExpr(boolean inParens) throws ParseException { - if( !Keyword("function",inParens) ) + private Expr FunctionExpr(In in) throws ParseException { + if( !Keyword("function",in) ) return null; - return RequiredFunction(inParens); + return RequiredFunction(in); } - private FnDef RequiredFunction(boolean inParens) throws ParseException { + private FnDef RequiredFunction(In in) throws ParseException { int start = parser.begin(); RequiredMatch('('); - Spaces(true); + In inParens = in.parens(); + Spaces(inParens); frame = new Frame(frame); - List<String> names = NameList(false); + List<String> names = NameList(in); if( names != null ) { addSymbols(names); if( parser.match(',') ) { - Spaces(true); + Spaces(inParens); if( !parser.match("...") ) throw parser.exception(); frame.isVarArg = true; } } else if( parser.match("...") ) { - Spaces(true); + Spaces(inParens); frame.isVarArg = true; } RequiredMatch(')'); - Spaces(inParens); + Spaces(in); Stmt block = RequiredBlock(); - RequiredKeyword("end",inParens); + RequiredKeyword("end",in); FnDef fnDef = newFnDef(start,block); frame = frame.parent; return parser.success(fnDef); } - private VarArgs VarArgs(boolean inParens) throws ParseException { + private VarArgs VarArgs(In in) throws ParseException { int start = parser.begin(); if( !frame.isVarArg || !parser.match("...") ) return parser.failure(null); - Spaces(inParens); + Spaces(in); return parser.success( new VarArgs(se(start)) ); } - private Expr TableExpr(boolean inParens) throws ParseException { + private Expr TableExpr(In in) throws ParseException { int start = parser.begin(); if( !parser.match('{') ) return parser.failure(null); - Spaces(true); + In inParens = in.parens(); + Spaces(inParens); List<TableExpr.Field> fields = new ArrayList<TableExpr.Field>(); ExpList.Builder builder = new ExpList.Builder(); - while( Field(fields,builder) && FieldSep() ); + while( Field(fields,builder,in) && FieldSep(inParens) ); if( !parser.match('}') ) throw parser.exception("Expected table element or '}'"); return parser.success( new TableExpr( se(start), fields.toArray(new TableExpr.Field[0]), builder.build() ) ); } - private boolean FieldSep() throws ParseException { + private boolean FieldSep(In in) throws ParseException { if( !parser.anyOf(",;") ) return false; - Spaces(true); + Spaces(in); return true; } - private boolean Field(List<TableExpr.Field> fields,ExpList.Builder builder) throws ParseException { + private boolean Field(List<TableExpr.Field> fields,ExpList.Builder builder,In in) throws ParseException { parser.begin(); - Expr exp = SubExpr(true); + Expr exp = SubExpr(in); if( exp==null ) - exp = NameExpr(true); + exp = NameExpr(in); if( exp!=null && parser.match('=') ) { - fields.add( new TableExpr.Field( exp, required(expr(Expr(true))) ) ); + fields.add( new TableExpr.Field( exp, required(expr(Expr(in))) ) ); return parser.success(); } parser.rollback(); - Code code = Expr(true); + Code code = Expr(in); if( code != null ) { builder.add(code); return parser.success(); @@ -771,75 +788,76 @@ return parser.failure(); } - private Code VarExp(boolean inParens) throws ParseException { - Var var = VarZ(inParens); + private Code VarExp(In in) throws ParseException { + Var var = VarZ(in); return var==null ? null : var.expr(); } - private Var VarZ(boolean inParens) throws ParseException { + private Var VarZ(In in) throws ParseException { int start = parser.begin(); - Var var = VarStart(inParens); + Var var = VarStart(in); if( var==null ) return parser.failure(null); Var var2; - while( (var2=Var2(inParens,start,var.expr())) != null ) { + while( (var2=Var2(in,start,var.expr())) != null ) { var = var2; } return parser.success(var); } - private Var Var2(boolean inParens,int start,Code exp1) throws ParseException { - Var var = VarExt(inParens,start,exp1); + private Var Var2(In in,int start,Code exp1) throws ParseException { + Var var = VarExt(in,start,exp1); if( var != null ) return var; if( parser.match("->") ) { - Spaces(inParens); + Spaces(in); ExpList.Builder builder = new ExpList.Builder(); builder.add(exp1); - Expr exp2 = expr(RequiredVarExpB(inParens)); - FnCall fnCall = required(Args( inParens, start, exp2, builder )); + Expr exp2 = expr(RequiredVarExpB(in)); + FnCall fnCall = required(Args( in, start, exp2, builder )); return exprVar(fnCall); } - FnCall fnCall = Args( inParens, start, expr(exp1), new ExpList.Builder() ); + FnCall fnCall = Args( in, start, expr(exp1), new ExpList.Builder() ); if( fnCall != null ) return exprVar(fnCall); return null; } - private Code RequiredVarExpB(boolean inParens) throws ParseException { + private Code RequiredVarExpB(In in) throws ParseException { int start = parser.begin(); - Var var = required(VarStart(inParens)); + Var var = required(VarStart(in)); Var var2; - while( (var2=VarExt(inParens,start,var.expr())) != null ) { + while( (var2=VarExt(in,start,var.expr())) != null ) { var = var2; } return parser.success(var.expr()); } - private Var VarExt(boolean inParens,int start,Code exp1) throws ParseException { + private Var VarExt(In in,int start,Code exp1) throws ParseException { parser.begin(); - Expr exp2 = SubExpr(inParens); + Expr exp2 = SubExpr(in); if( exp2 != null ) return parser.success(indexVar(start,expr(exp1),exp2)); if( parser.match('.') ) { - Spaces(inParens); - exp2 = NameExpr(inParens); + Spaces(in); + exp2 = NameExpr(in); if( exp2!=null ) return parser.success(indexVar(start,expr(exp1),exp2)); } return parser.failure(null); } - private Var VarStart(boolean inParens) throws ParseException { + private Var VarStart(In in) throws ParseException { int start = parser.begin(); if( parser.match('(') ) { - Spaces(true); - Expr exp = expr(Expr(true)); + In inParens = in.parens(); + Spaces(inParens); + Expr exp = expr(Expr(inParens)); RequiredMatch(')'); - Spaces(inParens); + Spaces(in); return parser.success(exprVar(exp)); } - String name = Name(inParens); + String name = Name(in); if( name != null ) return parser.success(nameVar(start,name)); return parser.failure(null); @@ -911,33 +929,34 @@ }; } - private FnCall Args(boolean inParens,int start,Expr fn,ExpList.Builder builder) throws ParseException { + private FnCall Args(In in,int start,Expr fn,ExpList.Builder builder) throws ParseException { parser.begin(); - return args(inParens,builder) + return args(in,builder) ? parser.success( new FnCall( se(start), fn, builder.build() ) ) : parser.failure((FnCall)null); } - private boolean args(boolean inParens,ExpList.Builder builder) throws ParseException { + private boolean args(In in,ExpList.Builder builder) throws ParseException { if( parser.match('(') ) { - Spaces(true); - ExpList(true,builder); // optional + In inParens = in.parens(); + Spaces(inParens); + ExpList(inParens,builder); // optional if( !parser.match(')') ) throw parser.exception("Expression or ')' expected"); - Spaces(inParens); + Spaces(in); return true; } - Expr exp = TableExpr(inParens); + Expr exp = TableExpr(in); if( exp != null ) { builder.add(exp); return true; } - String s = StringLiteral(inParens); + String s = StringLiteral(in); if( s != null ) { builder.add( new ConstExpr(s) ); return true; } - Expressions exps = JspExpressions(); + Expressions exps = JspExpressions(in); if( exps != null ) { builder.add(exps); return true; @@ -945,57 +964,50 @@ return false; } - private Expressions ExpList() throws ParseException { - return ExpList(false); + private Expressions ExpList(In in) throws ParseException { + ExpList.Builder builder = new ExpList.Builder(); + return ExpList(in,builder) ? builder.build() : null; } - private Expressions ExpList(boolean inParens) throws ParseException { - ExpList.Builder builder = new ExpList.Builder(); - return ExpList(inParens,builder) ? builder.build() : null; - } - - private boolean ExpList(boolean inParens,ExpList.Builder builder) throws ParseException { + private boolean ExpList(In in,ExpList.Builder builder) throws ParseException { parser.begin(); - Code exp = Expr(inParens); + Code exp = Expr(in); if( exp==null ) return parser.failure(); builder.add(exp); while( parser.match(',') ) { - Spaces(inParens); - builder.add( RequiredExpr(inParens) ); + Spaces(in); + builder.add( RequiredExpr(in) ); } return parser.success(); } - private Expr SubExpr(boolean inParens) throws ParseException { + private Expr SubExpr(In in) throws ParseException { parser.begin(); if( !parser.match('[') ) return parser.failure(null); - Spaces(true); - Expr exp = expr(RequiredExpr(true)); + In inParens = in.parens(); + Spaces(inParens); + Expr exp = expr(RequiredExpr(inParens)); RequiredMatch(']'); - Spaces(inParens); + Spaces(in); return parser.success(exp); } - private Expr NameExpr(boolean inParens) throws ParseException { - String name = Name(inParens); + private Expr NameExpr(In in) throws ParseException { + String name = Name(in); return name==null ? null : new ConstExpr(name); } - private String RequiredName() throws ParseException { + private String RequiredName(In in) throws ParseException { parser.begin(); - String name = Name(); + String name = Name(in); if( name==null ) parser.exception("Name expected"); return parser.success(name); } - private String Name() throws ParseException { - return Name(false); - } - - private String Name(boolean inParens) throws ParseException { + private String Name(In in) throws ParseException { int start = parser.begin(); if( !NameFirstChar() ) return parser.failure(null); @@ -1003,7 +1015,7 @@ String match = parser.textFrom(start); if( keywords.contains(match) ) return parser.failure(null); - Spaces(inParens); + Spaces(in); return parser.success(match); } @@ -1025,24 +1037,16 @@ throw parser.exception("'"+s+"' expected"); } - private void RequiredKeyword(String keyword) throws ParseException { - RequiredKeyword(keyword,false); - } - - private boolean Keyword(String keyword) throws ParseException { - return Keyword(keyword,false); - } - - private void RequiredKeyword(String keyword,boolean inParens) throws ParseException { - if( !Keyword(keyword,inParens) ) + private void RequiredKeyword(String keyword,In in) throws ParseException { + if( !Keyword(keyword,in) ) throw parser.exception("'"+keyword+"' expected"); } - private boolean Keyword(String keyword,boolean inParens) throws ParseException { + private boolean Keyword(String keyword,In in) throws ParseException { parser.begin(); if( !parser.match(keyword) || NameChar() ) return parser.failure(); - Spaces(inParens); + Spaces(in); return parser.success(); } @@ -1074,34 +1078,34 @@ "while" )); - private Expr Literal(boolean inParens) throws ParseException { - if( NilLiteral(inParens) ) + private Expr Literal(In in) throws ParseException { + if( NilLiteral(in) ) return new ConstExpr(null); - Boolean b = BooleanLiteral(inParens); + Boolean b = BooleanLiteral(in); if( b != null ) return new ConstExpr(b); - Number n = NumberLiteral(inParens); + Number n = NumberLiteral(in); if( n != null ) return new ConstExpr(n); - String s = StringLiteral(inParens); + String s = StringLiteral(in); if( s != null ) return new ConstExpr(s); return null; } - private boolean NilLiteral(boolean inParens) throws ParseException { - return Keyword("nil",inParens); + private boolean NilLiteral(In in) throws ParseException { + return Keyword("nil",in); } - private Boolean BooleanLiteral(boolean inParens) throws ParseException { - if( Keyword("true",inParens) ) + private Boolean BooleanLiteral(In in) throws ParseException { + if( Keyword("true",in) ) return true; - if( Keyword("false",inParens) ) + if( Keyword("false",in) ) return false; return null; } - private Number NumberLiteral(boolean inParens) throws ParseException { + private Number NumberLiteral(In in) throws ParseException { parser.begin(); Number n; if( parser.matchIgnoreCase("0x") ) { @@ -1111,7 +1115,7 @@ } if( n==null || NameChar() ) return parser.failure(null); - Spaces(inParens); + Spaces(in); return parser.success(n); } @@ -1189,14 +1193,14 @@ return Digit() || parser.anyOf("abcdefABCDEF"); } - private String StringLiteral(boolean inParens) throws ParseException { + private String StringLiteral(In in) throws ParseException { String s; if( (s=QuotedString('"'))==null && (s=QuotedString('\''))==null && (s=LongString())==null ) return null; - Spaces(inParens); + Spaces(in); return s; } @@ -1261,12 +1265,8 @@ return parser.failure(null); } - private void Spaces() throws ParseException { - Spaces(false); - } - - private void Spaces(boolean inParens) throws ParseException { - while( parser.anyOf(" \t") || Comment() || ContinueOnNextLine() || inParens && NewLine() ); + private void Spaces(In in) throws ParseException { + while( parser.anyOf(" \t") || Comment() || ContinueOnNextLine() || in.parens && NewLine() ); } private boolean ContinueOnNextLine() {