Improve ast classes and visitor.

This commit is contained in:
James Roseborough
2010-06-24 05:15:41 +00:00
parent f50d7eb7d3
commit bce5c5a5b7
11 changed files with 275 additions and 236 deletions

View File

@@ -47,16 +47,16 @@ public class LuaParser {
parser.Chunk();
}
private static VarExp assertvarexp(PrimaryExp pe) throws ParseException {
private static Exp.VarExp assertvarexp(Exp.PrimaryExp pe) throws ParseException {
if (!pe.isvarexp())
throw new ParseException("exptected variable");
return (VarExp) pe;
return (Exp.VarExp) pe;
}
private static FuncCall assertfunccall(PrimaryExp pe) throws ParseException {
private static Exp.FuncCall assertfunccall(Exp.PrimaryExp pe) throws ParseException {
if (!pe.isfunccall())
throw new ParseException("expected function call");
return (FuncCall) pe;
return (Exp.FuncCall) pe;
}
}
@@ -230,7 +230,7 @@ Stat LastStat():
Stat ExprStat():
{
PrimaryExp pe;
Exp.PrimaryExp pe;
Stat as=null;
}
{
@@ -238,20 +238,20 @@ Stat ExprStat():
{ return as==null? Stat.functioncall(assertfunccall(pe)): as; }
}
Stat Assign(VarExp v0):
Stat Assign(Exp.VarExp v0):
{
List<VarExp> vl = new ArrayList<VarExp>();
List<Exp.VarExp> vl = new ArrayList<Exp.VarExp>();
vl.add(v0);
VarExp ve;
Exp.VarExp ve;
List<Exp> el;
}
{
( "," ve=VarExp() { vl.add(ve); } )* "=" el=ExpList() { return Stat.assignment(vl,el); }
}
VarExp VarExp():
Exp.VarExp VarExp():
{
PrimaryExp pe;
Exp.PrimaryExp pe;
}
{
pe=PrimaryExp() { return assertvarexp(pe); }
@@ -269,36 +269,35 @@ FuncName FuncName():
{return fn;}
}
PrimaryExp PrefixExp():
Exp.PrimaryExp PrefixExp():
{
Token n;
Exp e;
}
{
n=<NAME> { return PrimaryExp.nameprefix(n.image); }
| "(" e=Exp() ")" { return PrimaryExp.parensprefix(e); }
n=<NAME> { return Exp.nameprefix(n.image); }
| "(" e=Exp() ")" { return Exp.parensprefix(e); }
}
PrimaryExp PrimaryExp():
Exp.PrimaryExp PrimaryExp():
{
PrimaryExp pe;
PostfixOp po;
Exp.PrimaryExp pe;
}
{
pe=PrefixExp() ( LOOKAHEAD(2) po=PostfixOp() {pe=pe.append(po);} )* { return pe; }
pe=PrefixExp() ( LOOKAHEAD(2) pe=PostfixOp(pe) )* { return pe; }
}
PostfixOp PostfixOp():
Exp.PrimaryExp PostfixOp(Exp.PrimaryExp lhs):
{
Token n;
Exp e;
FuncArgs a;
}
{
"." n=<NAME> { return PostfixOp.fieldop(n.image); }
| "[" e=Exp() "]" { return PostfixOp.indexop(e); }
| ":" n=<NAME> a=FuncArgs() { return PostfixOp.methodop(n.image,a); }
| a=FuncArgs() { return PostfixOp.functionop(a); }
"." n=<NAME> { return Exp.fieldop(lhs, n.image); }
| "[" e=Exp() "]" { return Exp.indexop(lhs, e); }
| ":" n=<NAME> a=FuncArgs() { return Exp.methodop(lhs, n.image,a); }
| a=FuncArgs() { return Exp.functionop(lhs, a); }
}
FuncArgs FuncArgs():
@@ -403,30 +402,30 @@ ParList ParList():
TableConstructor TableConstructor():
{
TableConstructor tc = new TableConstructor();
List<Field> fl = null;
List<TableField> fl = null;
}
{
"{" ( fl=FieldList() {tc.fields=fl;} )? "}" { return tc; }
}
List<Field> FieldList():
List<TableField> FieldList():
{
List<Field> fl = new ArrayList<Field>();
Field f;
List<TableField> fl = new ArrayList<TableField>();
TableField f;
}
{
f=Field() {fl.add(f);} (LOOKAHEAD(2) FieldSep() f=Field() {fl.add(f);})* (FieldSep())? { return fl; }
}
Field Field():
TableField Field():
{
Token name;
Exp exp,rhs;
}
{
"[" exp=Exp() "]" "=" rhs=Exp() { return Field.keyedField(exp,rhs); }
| LOOKAHEAD(2) name=<NAME> "=" rhs=Exp() { return Field.namedField(name.image,rhs); }
| rhs=Exp() { return Field.listField(rhs); }
"[" exp=Exp() "]" "=" rhs=Exp() { return TableField.keyedField(exp,rhs); }
| LOOKAHEAD(2) name=<NAME> "=" rhs=Exp() { return TableField.namedField(name.image,rhs); }
| rhs=Exp() { return TableField.listField(rhs); }
}
void FieldSep():

View File

@@ -51,6 +51,142 @@ public class Exp {
return new AnonFuncDef(funcbody);
}
/** foo */
public static NameExp nameprefix(String name) {
return new NameExp(name);
}
/** ( foo.bar ) */
public static ParensExp parensprefix(Exp exp) {
return new ParensExp(exp);
}
/** foo[exp] */
public static IndexExp indexop(PrimaryExp lhs, Exp exp) {
return new IndexExp(lhs, exp);
}
/** foo.bar */
public static FieldExp fieldop(PrimaryExp lhs, String name) {
return new FieldExp(lhs, name);
}
/** foo(2,3) */
public static FuncCall functionop(PrimaryExp lhs, FuncArgs args) {
return new FuncCall(lhs, args);
}
/** foo:bar(4,5) */
public static MethodCall methodop(PrimaryExp lhs, String name, FuncArgs args) {
return new MethodCall(lhs, name, args);
}
public boolean isvarexp() {
return false;
}
public boolean isfunccall() {
return false;
}
abstract public static class PrimaryExp extends Exp {
public boolean isvarexp() {
return false;
}
public boolean isfunccall() {
return false;
}
}
abstract public static class VarExp extends PrimaryExp {
public boolean isvarexp() {
return true;
}
}
public static class NameExp extends VarExp {
public final Name name;
public NameExp(String name) {
this.name = new Name(name);
}
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
public static class ParensExp extends PrimaryExp {
public final Exp exp;
public ParensExp(Exp exp) {
this.exp = exp;
}
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
public static class FieldExp extends VarExp {
public final PrimaryExp lhs;
public final Name name;
public FieldExp(PrimaryExp lhs, String name) {
this.lhs = lhs;
this.name = new Name(name);
}
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
public static class IndexExp extends VarExp {
public final PrimaryExp lhs;
public final Exp exp;
public IndexExp(PrimaryExp lhs, Exp exp) {
this.lhs = lhs;
this.exp = exp;
}
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
public static class FuncCall extends PrimaryExp {
public final PrimaryExp lhs;
public final FuncArgs args;
public FuncCall(PrimaryExp lhs, FuncArgs args) {
this.lhs = lhs;
this.args = args;
}
public boolean isfunccall() {
return true;
}
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
public static class MethodCall extends FuncCall {
public final String name;
public MethodCall(PrimaryExp lhs, String name, FuncArgs args) {
super(lhs, args);
this.name = new String(name);
}
public boolean isfunccall() {
return true;
}
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
public static class Constant extends Exp {
public final LuaValue value;
public Constant(LuaValue value) {

View File

@@ -1,30 +0,0 @@
/*******************************************************************************
* Copyright (c) 2010 Luaj.org. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
package org.luaj.vm2.ast;
public class FuncCall extends PrimaryExp {
public void accept(Visitor visitor) {
visitor.visit(this);
}
}

View File

@@ -1,61 +0,0 @@
/*******************************************************************************
* Copyright (c) 2010 Luaj.org. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
package org.luaj.vm2.ast;
public class PostfixOp {
/** foo[exp] */
public static PostfixOp indexop(Exp e) {
// TODO Auto-generated method stub
return null;
}
/** foo.name */
public static PostfixOp fieldop(String name) {
// TODO Auto-generated method stub
return null;
}
/** foo:name(args) */
public static PostfixOp methodop(String name, FuncArgs args) {
// TODO Auto-generated method stub
return null;
}
/** foo(args) */
public static PostfixOp functionop(FuncArgs a) {
// TODO Auto-generated method stub
return null;
}
public boolean isvarop() {
return false;
}
public boolean isfunccall() {
return false;
}
public void accept(Visitor visitor) {
visitor.visit(this);
}
}

View File

@@ -1,57 +0,0 @@
/*******************************************************************************
* Copyright (c) 2010 Luaj.org. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
package org.luaj.vm2.ast;
import java.util.ArrayList;
import java.util.List;
public class PrimaryExp extends Exp {
List<PostfixOp> ops;
public static PrimaryExp nameprefix(String image) {
return null;
}
public static PrimaryExp parensprefix(Exp e) {
return null;
}
public PrimaryExp append(PostfixOp op) {
if ( ops == null )
ops = new ArrayList<PostfixOp>();
ops.add( op );
return this;
}
public boolean isvarexp() {
return ops != null && ops.get(ops.size()-1).isvarop();
}
public boolean isfunccall() {
return ops != null && ops.get(ops.size()-1).isfunccall();
}
public void accept(Visitor visitor) {
visitor.visit(this);
}
}

View File

@@ -47,11 +47,11 @@ public class Stat {
return new Return(exps);
}
public static Stat assignment(List<VarExp> vars, List<Exp> exps) {
public static Stat assignment(List<Exp.VarExp> vars, List<Exp> exps) {
return new Assign(vars,exps);
}
public static Stat functioncall(FuncCall funccall) {
public static Stat functioncall(Exp.FuncCall funccall) {
return new FuncCallStat(funccall);
}
@@ -80,10 +80,10 @@ public class Stat {
}
public static class Assign extends Stat {
public final List<VarExp> vars;
public final List<Exp.VarExp> vars;
public final List<Exp> exps;
public Assign(List<VarExp> vars, List<Exp> exps) {
public Assign(List<Exp.VarExp> vars, List<Exp> exps) {
this.vars = vars;
this.exps = exps;
}
@@ -136,8 +136,8 @@ public class Stat {
}
public static class FuncCallStat extends Stat {
public final FuncCall funccall;
public FuncCallStat(FuncCall funccall) {
public final Exp.FuncCall funccall;
public FuncCallStat(Exp.FuncCall funccall) {
this.funccall = funccall;
}

View File

@@ -57,7 +57,7 @@ public class Str {
try {
return s.getBytes("UTF8");
} catch ( Exception e ) {
throw new RuntimeException("utf8 nto found: "+e);
throw new RuntimeException("utf8 not found: "+e);
}
}
}

View File

@@ -24,7 +24,7 @@ package org.luaj.vm2.ast;
import java.util.List;
public class TableConstructor extends Exp {
public List<Field> fields;
public List<TableField> fields;
public void accept(Visitor visitor) {
visitor.visit(this);

View File

@@ -21,28 +21,28 @@
******************************************************************************/
package org.luaj.vm2.ast;
public class Field {
public class TableField {
public final Exp index;
public final String name;
public final Exp rhs;
public Field(Exp index, String name, Exp rhs) {
public TableField(Exp index, String name, Exp rhs) {
this.index = index;
this.name = name;
this.rhs = rhs;
}
public static Field keyedField(Exp index, Exp rhs) {
return new Field(index, null, rhs);
public static TableField keyedField(Exp index, Exp rhs) {
return new TableField(index, null, rhs);
}
public static Field namedField(String name, Exp rhs) {
return new Field(null, name, rhs);
public static TableField namedField(String name, Exp rhs) {
return new TableField(null, name, rhs);
}
public static Field listField(Exp rhs) {
return new Field(null, null, rhs);
public static TableField listField(Exp rhs) {
return new TableField(null, null, rhs);
}
public void accept(Visitor visitor) {

View File

@@ -1,28 +0,0 @@
/*******************************************************************************
* Copyright (c) 2010 Luaj.org. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
package org.luaj.vm2.ast;
public class VarExp extends PrimaryExp {
public void accept(Visitor visitor) {
visitor.visit(this);
}
}

View File

@@ -1,64 +1,144 @@
package org.luaj.vm2.ast;
import java.util.List;
abstract public class Visitor {
public void visit(Chunk chunk) {
chunk.block.accept(this);
};
public void visit(Block block) {
if ( block.stats != null )
for ( Stat s : block.stats )
s.accept( this );
for ( Stat s: block.stats )
s.accept(this);
};
public void visit(Stat.Assign assign) {
public void visit(Stat.Assign stat) {
visitVars(stat.vars);
visitExps(stat.exps);
}
public void visit(Stat.Break breakstat) {
}
public void visit(Stat.FuncCallStat stat) {
stat.funccall.accept(this);
}
public void visit(Stat.FuncDef stat) {
stat.body.accept(this);
}
public void visit(Stat.GenericFor stat) {
visitNames(stat.names);
visitExps(stat.exps);
stat.block.accept(this);
}
public void visit(Stat.IfThenElse stat) {
stat.ifexp.accept(this);
stat.ifblock.accept(this);
for ( int i=0, n=stat.elseifblocks.size(); i<n; i++ ) {
stat.elseifexps.get(i).accept(this);
stat.elseifblocks.get(i).accept(this);
}
visit( stat.elseblock );
}
public void visit(Stat.LocalAssign stat) {
visitNames(stat.names);
visitExps(stat.values);
}
public void visit(Stat.LocalFuncDef stat) {
visit(stat.name);
stat.body.accept(this);
}
public void visit(Stat.NumericFor stat) {
visit(stat.name);
stat.initial.accept(this);
stat.step.accept(this);
stat.limit.accept(this);
stat.block.accept(this);
}
public void visit(Stat.RepeatUntil stat) {
stat.block.accept(this);
stat.exp.accept(this);
}
public void visit(Stat.Return stat) {
visitExps(stat.values);
}
public void visit(Stat.WhileDo stat) {
stat.exp.accept(this);
stat.block.accept(this);
}
public void visit(FuncCall funcCall) {
public void visit(FuncBody body) {
body.parlist.accept(this);
body.block.accept(this);
}
public void visit(FuncBody funcBody) {
public void visit(FuncArgs args) {
visitExps(args.exps);
}
public void visit(FuncArgs funcArgs) {
}
public void visit(Field field) {
}
public void visit(Exp exp) {
public void visit(TableField field) {
if ( field.name != null );
visit( field.name );
if ( field.index != null )
field.index.accept(this);
field.rhs.accept(this);
}
public void visit(Exp.AnonFuncDef exp) {
exp.funcbody.accept(this);
}
public void visit(Exp.BinopExp exp) {
exp.lhs.accept(this);
exp.rhs.accept(this);
}
public void visit(Exp.Constant exp) {
}
public void visit(Exp.FieldExp exp) {
exp.lhs.accept(this);
visit(exp.name);
}
public void visit(Exp.FuncCall exp) {
exp.lhs.accept(this);
exp.args.accept(this);
}
public void visit(Exp.IndexExp exp) {
exp.lhs.accept(this);
exp.exp.accept(this);
}
public void visit(Exp.MethodCall exp) {
exp.lhs.accept(this);
visit(exp.name);
exp.args.accept(this);
}
public void visit(Exp.NameExp exp) {
visit(exp.name);
}
public void visit(Exp.ParensExp exp) {
exp.exp.accept(this);
}
public void visit(Exp.UnopExp exp) {
exp.rhs.accept(this);
}
public void visit(Exp.VarargsExp exp) {
}
public void visit(PrimaryExp exp) {
public void visit(ParList pars) {
visitNames(pars.names);
}
public void visit(ParList parList) {
public void visit(TableConstructor table) {
if( table.fields != null)
for ( TableField f: table.fields )
f.accept(this);
}
public void visit(PostfixOp postfixOp) {
public void visitVars(List<Exp.VarExp> vars) {
if ( vars != null )
for ( Exp.VarExp v: vars )
v.accept(this);
}
public void visit(VarExp exp) {
public void visitExps(List<Exp> exps) {
if ( exps != null )
for ( Exp e: exps )
e.accept(this);
}
public void visitNames(List<Name> names) {
if ( names != null )
for ( Name n: names )
visit(n);
}
private void visit(Name name) {
}
private void visit(String name) {
}
}