Add lua2java too to compile from lua source to java source
This commit is contained in:
197
src/jse/lua2java.java
Normal file
197
src/jse/lua2java.java
Normal file
@@ -0,0 +1,197 @@
|
||||
/*******************************************************************************
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.luaj.vm2.Lua;
|
||||
import org.luaj.vm2.ast.Chunk;
|
||||
import org.luaj.vm2.lua2java.JavaCodeGen;
|
||||
import org.luaj.vm2.parser.LuaParser;
|
||||
|
||||
/**
|
||||
* Compile lua sources into java sources.
|
||||
*/
|
||||
public class lua2java {
|
||||
private static final String version = Lua._VERSION + "Copyright (C) 2010 luaj.org";
|
||||
|
||||
private static final String usage =
|
||||
"usage: java -cp luaj-jse.jar lua2java [options] [filenames].\n" +
|
||||
"Available options are:\n" +
|
||||
" - process stdin\n" +
|
||||
" -s src source directory\n" +
|
||||
" -d dir destination directory\n" +
|
||||
" -p pkg package prefix to apply to all classes\n" +
|
||||
" -r recursively compile all\n" +
|
||||
" -v verbose\n";
|
||||
|
||||
private static void usageExit() {
|
||||
System.out.println(usage);
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
private String srcdir = null;
|
||||
private String destdir = null;
|
||||
private String pkgprefix = null;
|
||||
private boolean recurse = false;
|
||||
private boolean verbose = false;
|
||||
private List<InputFile> files = new ArrayList<InputFile>();
|
||||
|
||||
public static void main( String[] args ) throws IOException {
|
||||
new lua2java( args );
|
||||
}
|
||||
|
||||
private lua2java( String[] args ) throws IOException {
|
||||
|
||||
// process args
|
||||
try {
|
||||
List<String> seeds = new ArrayList<String> ();
|
||||
|
||||
// get stateful args
|
||||
for ( int i=0; i<args.length; i++ ) {
|
||||
if ( ! args[i].startsWith("-") ) {
|
||||
seeds.add(args[i]);
|
||||
} else {
|
||||
switch ( args[i].charAt(1) ) {
|
||||
case 's':
|
||||
if ( ++i >= args.length )
|
||||
usageExit();
|
||||
srcdir = args[i];
|
||||
break;
|
||||
case 'd':
|
||||
if ( ++i >= args.length )
|
||||
usageExit();
|
||||
destdir = args[i];
|
||||
break;
|
||||
case 'p':
|
||||
if ( ++i >= args.length )
|
||||
usageExit();
|
||||
pkgprefix = args[i];
|
||||
break;
|
||||
case 'r':
|
||||
recurse = true;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = true;
|
||||
break;
|
||||
default:
|
||||
usageExit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// echo version
|
||||
if ( verbose ) {
|
||||
System.out.println(version);
|
||||
System.out.println("srcdir: "+srcdir);
|
||||
System.out.println("destdir: "+destdir);
|
||||
System.out.println("files: "+files);
|
||||
System.out.println("recurse: "+recurse);
|
||||
}
|
||||
|
||||
// collect up files to process
|
||||
for ( int i=0; i<seeds.size(); i++ )
|
||||
collectFiles( seeds.get(i) );
|
||||
|
||||
// check for at least one file
|
||||
if ( files.size() <= 0 ) {
|
||||
System.err.println("no files found in "+seeds);
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
// process input files
|
||||
for ( InputFile inf : files )
|
||||
processFile( inf );
|
||||
|
||||
} catch ( Exception ioe ) {
|
||||
System.err.println( ioe.toString() );
|
||||
System.exit(-2);
|
||||
}
|
||||
}
|
||||
|
||||
private void collectFiles(String path) {
|
||||
File f = new File(path);
|
||||
if ( f.isDirectory() && recurse )
|
||||
scandir(f,pkgprefix);
|
||||
else if ( f.isFile() ) {
|
||||
File dir = f.getAbsoluteFile().getParentFile();
|
||||
if ( dir != null )
|
||||
scanfile( dir, f, pkgprefix );
|
||||
}
|
||||
}
|
||||
private void scandir(File dir, String javapackage) {
|
||||
File[] f = dir.listFiles();
|
||||
for ( int i=0; i<f.length; i++ )
|
||||
scanfile( dir, f[i], javapackage );
|
||||
}
|
||||
|
||||
private void scanfile(File dir, File f, String javapackage) {
|
||||
if ( f.exists() ) {
|
||||
if ( f.isDirectory() && recurse )
|
||||
scandir( f, (javapackage!=null? javapackage+"."+f.getName(): f.getName()) );
|
||||
else if ( f.isFile() && f.getName().endsWith(".lua") )
|
||||
files.add( new InputFile(dir,f,javapackage) );
|
||||
}
|
||||
}
|
||||
|
||||
class InputFile {
|
||||
public File infile;
|
||||
public File outdir;
|
||||
public File outfile;
|
||||
public String javapackage;
|
||||
public String javaclassname;
|
||||
public InputFile(File dir, File f, String javapackage) {
|
||||
String outdirpath = javapackage!=null? destdir+"/"+javapackage.replace('.', '/'): destdir;
|
||||
this.javaclassname = f.getName().substring(0,f.getName().lastIndexOf('.'));
|
||||
this.javapackage = javapackage;
|
||||
this.infile = f;
|
||||
this.outdir = new File(outdirpath);
|
||||
this.outfile = new File(outdirpath+"/"+this.javaclassname+".java");
|
||||
}
|
||||
}
|
||||
|
||||
private void processFile( InputFile inf ) {
|
||||
inf.outdir.mkdirs();
|
||||
try {
|
||||
if ( verbose )
|
||||
System.out.println(
|
||||
"pkg="+inf.javapackage+" file="+inf.javaclassname+".java dest="+inf.outfile+" src="+inf.infile);
|
||||
FileInputStream in = new FileInputStream(inf.infile);
|
||||
FileOutputStream out = new FileOutputStream(inf.outfile);
|
||||
PrintWriter pw = new PrintWriter(out);
|
||||
LuaParser parser = new LuaParser(in);
|
||||
Chunk chunk = parser.Chunk();
|
||||
new JavaCodeGen(chunk,pw,inf.javapackage,inf.javaclassname);
|
||||
pw.close();
|
||||
out.close();
|
||||
in.close();
|
||||
} catch ( Throwable t ) {
|
||||
t.printStackTrace( System.err );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2.ast;
|
||||
|
||||
import org.luaj.vm2.Lua;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
|
||||
abstract
|
||||
@@ -40,13 +41,59 @@ public class Exp {
|
||||
}
|
||||
|
||||
public static Exp unaryexp(int op, Exp rhs) {
|
||||
if ( rhs instanceof BinopExp ) {
|
||||
BinopExp b = (BinopExp) rhs;
|
||||
if ( precedence(op) > precedence(b.op) )
|
||||
return binaryexp( unaryexp(op, b.lhs), b.op, b.rhs );
|
||||
}
|
||||
return new UnopExp(op, rhs);
|
||||
}
|
||||
|
||||
public static Exp binaryexp(Exp lhs, int op, Exp rhs) {
|
||||
if ( lhs instanceof UnopExp ) {
|
||||
UnopExp u = (UnopExp) lhs;
|
||||
if ( precedence(op) > precedence(u.op) )
|
||||
return unaryexp( u.op, binaryexp( u.rhs, op, rhs ) );
|
||||
}
|
||||
// TODO: cumulate string concatenations together
|
||||
// TODO: constant folding
|
||||
if ( lhs instanceof BinopExp ) {
|
||||
BinopExp b = (BinopExp) lhs;
|
||||
if ( (precedence(op) > precedence(b.op)) ||
|
||||
((precedence(op) == precedence(b.op)) && isrightassoc(op)) )
|
||||
return binaryexp( b.lhs, b.op, binaryexp( b.rhs, op, rhs ) );
|
||||
}
|
||||
if ( rhs instanceof BinopExp ) {
|
||||
BinopExp b = (BinopExp) rhs;
|
||||
if ( (precedence(op) > precedence(b.op)) ||
|
||||
((precedence(op) == precedence(b.op)) && ! isrightassoc(op)) )
|
||||
return binaryexp( binaryexp( lhs, op, b.lhs ), b.op, b.rhs );
|
||||
}
|
||||
return new BinopExp(lhs, op, rhs);
|
||||
}
|
||||
|
||||
static boolean isrightassoc(int op) {
|
||||
switch ( op ) {
|
||||
case Lua.OP_CONCAT:
|
||||
case Lua.OP_POW: return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
static int precedence(int op) {
|
||||
switch ( op ) {
|
||||
case Lua.OP_OR: return 0;
|
||||
case Lua.OP_AND: return 1;
|
||||
case Lua.OP_LT: case Lua.OP_GT: case Lua.OP_LE: case Lua.OP_GE: case Lua.OP_NEQ: case Lua.OP_EQ: return 2;
|
||||
case Lua.OP_CONCAT: return 3;
|
||||
case Lua.OP_ADD: case Lua.OP_SUB: return 4;
|
||||
case Lua.OP_MUL: case Lua.OP_DIV: return 5;
|
||||
case Lua.OP_NOT: case Lua.OP_UNM: case Lua.OP_LEN: return 6;
|
||||
case Lua.OP_POW: return 7;
|
||||
default: throw new IllegalStateException("precedence of bad op "+op);
|
||||
}
|
||||
}
|
||||
|
||||
public static Exp anonymousfunction(FuncBody funcbody) {
|
||||
return new AnonFuncDef(funcbody);
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ public class NameResolver extends Visitor {
|
||||
pushScope();
|
||||
scope.functionNestingCount++;
|
||||
body.scope = scope;
|
||||
if ( body.parlist.names != null )
|
||||
for ( Name n : body.parlist.names )
|
||||
defineLocalVar(n);
|
||||
super.visit(body);
|
||||
|
||||
@@ -135,6 +135,13 @@ public class Stat {
|
||||
public void accept(Visitor visitor) {
|
||||
visitor.visit( this );
|
||||
}
|
||||
|
||||
public int nreturns() {
|
||||
int n = values!=null? values.size(): 0;
|
||||
if ( n>0 && values.get(n-1).isvarargexp() )
|
||||
n = -1;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
public static class FuncCallStat extends Stat {
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2.ast;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
import org.luaj.vm2.LuaString;
|
||||
|
||||
public class Str {
|
||||
@@ -50,9 +52,39 @@ public class Str {
|
||||
return LuaString.valueOf(s);
|
||||
}
|
||||
public static byte[] unquote(String s) {
|
||||
// TODO: unquote string data
|
||||
return utf8decode(s);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
char[] c = s.toCharArray();
|
||||
int n = c.length;
|
||||
for ( int i=0; i<n; i++ ) {
|
||||
if ( c[i] == '\\' && i<n ) {
|
||||
switch ( c[++i] ) {
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
int d=(int) (c[i++]-'0');
|
||||
for ( int j=0; i<n && j<2 && c[i]>='0' && c[i]<='9'; i++, j++ )
|
||||
d = d * 10 + (int) (c[i]-'0');
|
||||
baos.write( (byte) d );
|
||||
--i;
|
||||
continue;
|
||||
case 'a': baos.write( (byte) 7 ); continue;
|
||||
case 'b': baos.write( (byte) '\b' ); continue;
|
||||
case 'f': baos.write( (byte) '\f' ); continue;
|
||||
case 'n': baos.write( (byte) '\n' ); continue;
|
||||
case 'r': baos.write( (byte) '\r' ); continue;
|
||||
case 't': baos.write( (byte) '\t' ); continue;
|
||||
case 'v': baos.write( (byte) 11 ); continue;
|
||||
case '"': baos.write( (byte) '"' ); continue;
|
||||
case '\'': baos.write( (byte) '\'' ); continue;
|
||||
case '\\': baos.write( (byte) '\\' ); continue;
|
||||
default: baos.write( (byte) c[i] ); break;
|
||||
}
|
||||
} else {
|
||||
baos.write( (byte) c[i] );
|
||||
}
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
/*
|
||||
private static byte[] utf8decode(String s) {
|
||||
try {
|
||||
return s.getBytes("UTF8");
|
||||
@@ -60,4 +92,5 @@ public class Str {
|
||||
throw new RuntimeException("utf8 not found: "+e);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -33,10 +33,12 @@ abstract public class Visitor {
|
||||
public void visit(Stat.IfThenElse stat) {
|
||||
stat.ifexp.accept(this);
|
||||
stat.ifblock.accept(this);
|
||||
if ( stat.elseifblocks != null )
|
||||
for ( int i=0, n=stat.elseifblocks.size(); i<n; i++ ) {
|
||||
stat.elseifexps.get(i).accept(this);
|
||||
stat.elseifblocks.get(i).accept(this);
|
||||
}
|
||||
if ( stat.elseblock != null )
|
||||
visit( stat.elseblock );
|
||||
}
|
||||
public void visit(Stat.LocalAssign stat) {
|
||||
|
||||
754
src/jse/org/luaj/vm2/lua2java/JavaCodeGen.java
Normal file
754
src/jse/org/luaj/vm2/lua2java/JavaCodeGen.java
Normal file
@@ -0,0 +1,754 @@
|
||||
/*******************************************************************************
|
||||
* 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.lua2java;
|
||||
|
||||
import java.io.CharArrayWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.luaj.vm2.Lua;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.ast.Block;
|
||||
import org.luaj.vm2.ast.Chunk;
|
||||
import org.luaj.vm2.ast.Exp;
|
||||
import org.luaj.vm2.ast.FuncArgs;
|
||||
import org.luaj.vm2.ast.FuncBody;
|
||||
import org.luaj.vm2.ast.Name;
|
||||
import org.luaj.vm2.ast.NameResolver;
|
||||
import org.luaj.vm2.ast.ParList;
|
||||
import org.luaj.vm2.ast.Stat;
|
||||
import org.luaj.vm2.ast.TableConstructor;
|
||||
import org.luaj.vm2.ast.TableField;
|
||||
import org.luaj.vm2.ast.Visitor;
|
||||
import org.luaj.vm2.ast.Exp.AnonFuncDef;
|
||||
import org.luaj.vm2.ast.Exp.BinopExp;
|
||||
import org.luaj.vm2.ast.Exp.Constant;
|
||||
import org.luaj.vm2.ast.Exp.FieldExp;
|
||||
import org.luaj.vm2.ast.Exp.FuncCall;
|
||||
import org.luaj.vm2.ast.Exp.IndexExp;
|
||||
import org.luaj.vm2.ast.Exp.MethodCall;
|
||||
import org.luaj.vm2.ast.Exp.NameExp;
|
||||
import org.luaj.vm2.ast.Exp.ParensExp;
|
||||
import org.luaj.vm2.ast.Exp.UnopExp;
|
||||
import org.luaj.vm2.ast.Exp.VarExp;
|
||||
import org.luaj.vm2.ast.Exp.VarargsExp;
|
||||
import org.luaj.vm2.ast.Stat.Assign;
|
||||
import org.luaj.vm2.ast.Stat.Break;
|
||||
import org.luaj.vm2.ast.Stat.FuncCallStat;
|
||||
import org.luaj.vm2.ast.Stat.FuncDef;
|
||||
import org.luaj.vm2.ast.Stat.GenericFor;
|
||||
import org.luaj.vm2.ast.Stat.IfThenElse;
|
||||
import org.luaj.vm2.ast.Stat.LocalAssign;
|
||||
import org.luaj.vm2.ast.Stat.LocalFuncDef;
|
||||
import org.luaj.vm2.ast.Stat.NumericFor;
|
||||
import org.luaj.vm2.ast.Stat.RepeatUntil;
|
||||
import org.luaj.vm2.ast.Stat.Return;
|
||||
import org.luaj.vm2.ast.Stat.WhileDo;
|
||||
|
||||
public class JavaCodeGen {
|
||||
|
||||
final Chunk chunk;
|
||||
final String packagename;
|
||||
final String classname;
|
||||
Writer writer;
|
||||
|
||||
public JavaCodeGen( Chunk chunk, Writer writer,String packagename, String classname) {
|
||||
this.chunk = chunk;
|
||||
this.writer = writer;
|
||||
this.packagename = packagename;
|
||||
this.classname = classname;
|
||||
chunk.accept( new NameResolver() );
|
||||
chunk.accept( new JavaClassWriterVisitor() );
|
||||
}
|
||||
|
||||
class JavaClassWriterVisitor extends Visitor {
|
||||
|
||||
JavaScope javascope = null;
|
||||
List<String> constantDeclarations = new ArrayList<String>();
|
||||
Map<String,String> stringConstants = new HashMap<String,String>();
|
||||
Map<Double,String> numberConstants = new HashMap<Double,String>();
|
||||
|
||||
|
||||
String indent = "";
|
||||
void addindent() {
|
||||
indent+=" ";
|
||||
}
|
||||
void subindent() {
|
||||
indent = indent.substring(3);
|
||||
}
|
||||
void out(String s) {
|
||||
try {
|
||||
writer.write(s);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("write failed: "+e, e);
|
||||
}
|
||||
}
|
||||
void outi(String s) {
|
||||
out( indent );
|
||||
out( s );
|
||||
}
|
||||
void outl(String s) {
|
||||
outi( s );
|
||||
out( "\n" );
|
||||
}
|
||||
void outr(String s) {
|
||||
out( s );
|
||||
out( "\n" );
|
||||
}
|
||||
void outb(String s) {
|
||||
outl( s );
|
||||
addindent();
|
||||
}
|
||||
void oute(String s) {
|
||||
subindent();
|
||||
outl( s );
|
||||
}
|
||||
|
||||
public void visit(Chunk chunk) {
|
||||
if ( packagename != null )
|
||||
outl("package "+packagename+";");
|
||||
outl("import org.luaj.vm2.*;");
|
||||
outl("import org.luaj.vm2.lib.*;");
|
||||
outb("public class "+classname+" extends VarArgFunction {");
|
||||
outl("public Varargs invoke(Varargs arg) {");
|
||||
addindent();
|
||||
javascope = JavaScope.newJavaScope( chunk );
|
||||
writeBodyBlock(chunk.block);
|
||||
oute("}");
|
||||
for ( String s : constantDeclarations )
|
||||
outl( s );
|
||||
subindent();
|
||||
outi("}");
|
||||
}
|
||||
|
||||
void writeBodyBlock(Block block) {
|
||||
if ( javascope.needsbinoptmp )
|
||||
outl( "LuaValue $b;" );
|
||||
super.visit(block);
|
||||
if ( !endsInReturn(block) )
|
||||
outl( "return NONE;" );
|
||||
}
|
||||
|
||||
public void visit(Block block) {
|
||||
outb("{");
|
||||
super.visit(block);
|
||||
oute("}");
|
||||
}
|
||||
|
||||
private boolean endsInReturn(Block block) {
|
||||
int n = block.stats.size();
|
||||
if ( n<=0 ) return false;
|
||||
Stat s = block.stats.get(n-1);
|
||||
return s instanceof Return || s instanceof Break;
|
||||
}
|
||||
|
||||
public void visit(Stat.Return s) {
|
||||
int n = s.nreturns();
|
||||
switch ( n ) {
|
||||
case 0: outl( "return NONE;" ); break;
|
||||
case 1: outl( "return "+eval(s.values.get(0))+";" ); break;
|
||||
default: outl( "return "+eval(s.values)+";" ); break;
|
||||
}
|
||||
}
|
||||
|
||||
public void visit(AnonFuncDef def) {
|
||||
super.visit(def);
|
||||
}
|
||||
|
||||
public void visit(LocalAssign stat) {
|
||||
int n = stat.names.size();
|
||||
int m = stat.values!=null? stat.values.size(): 0;
|
||||
if ( n == 1 && m<=1 ) {
|
||||
Name name = stat.names.get(0);
|
||||
String javaname = javascope.getJavaName(name.variable);
|
||||
String value = "NIL";
|
||||
if ( m > 0 ) {
|
||||
Exp val= stat.values.get(0);
|
||||
value = eval(val) + (val.isvarargexp()? ".arg1()": "");
|
||||
}
|
||||
singleLocalDeclareAssign(name,value);
|
||||
} else {
|
||||
for ( Name name : stat.names )
|
||||
singleLocalDeclareAssign(name,null);
|
||||
multiAssign(stat.names, stat.values);
|
||||
}
|
||||
}
|
||||
public void visit(Assign stat) {
|
||||
multiAssign(stat.vars, stat.exps);
|
||||
}
|
||||
private void multiAssign(List varsOrNames, List<Exp> exps) {
|
||||
int n = varsOrNames.size();
|
||||
int m = exps != null? exps.size(): 0;
|
||||
boolean varlist = m>0 && exps.get(m-1).isvarargexp() && n>m;
|
||||
if ( n<=m ) {
|
||||
for ( int i=1; i<=n; i++ )
|
||||
singleAssign( varsOrNames.get(i-1), eval(exps.get(i-1)) );
|
||||
for ( int i=n+1; i<=m; i++ )
|
||||
outl( eval(exps.get(i-1))+";" );
|
||||
} else {
|
||||
outb( "{" );
|
||||
for ( int i=1; i<=m; i++ ) {
|
||||
boolean vtype = varlist && (i==m);
|
||||
Exp e = exps.get(i-1);
|
||||
String decl = (vtype? "Varargs": "LuaValue")+" $"+i;
|
||||
String valu = eval(e)+(e.isvarexp() && !vtype? ".arg1()": "");
|
||||
outl( decl+"="+valu+";" );
|
||||
}
|
||||
for ( int i=1; i<=n; i++ ) {
|
||||
String valu;
|
||||
if ( i < m ) valu = "$"+i;
|
||||
else if ( i==m ) valu = (varlist? "$"+i+".arg1()": "$"+i);
|
||||
else if ( varlist ) valu = "$"+m+".arg("+(i-m+1)+")";
|
||||
else valu = "NIL";
|
||||
singleAssign( varsOrNames.get(i-1), valu );
|
||||
}
|
||||
oute( "}" );
|
||||
}
|
||||
}
|
||||
private void singleAssign(final Object varOrName, final String valu) {
|
||||
Visitor v = new Visitor() {
|
||||
public void visit(FieldExp exp) {
|
||||
outl(eval(exp.lhs)+".set("+evalStringConstant(exp.name.name)+","+valu+");");
|
||||
}
|
||||
public void visit(IndexExp exp) {
|
||||
outl(eval(exp.lhs)+".set("+eval(exp.exp)+","+valu+");");
|
||||
}
|
||||
public void visit(NameExp exp) {
|
||||
if ( exp.name.variable.isLocal() )
|
||||
singleLocalAssign(exp.name, valu);
|
||||
else
|
||||
outl( "env.set("+evalStringConstant(exp.name.name)+","+valu+");");
|
||||
}
|
||||
};
|
||||
if ( varOrName instanceof VarExp )
|
||||
((VarExp)varOrName).accept(v);
|
||||
else if ( varOrName instanceof Name )
|
||||
singleLocalAssign((Name) varOrName, valu);
|
||||
else
|
||||
throw new IllegalStateException("can't assign to "+varOrName.getClass());
|
||||
}
|
||||
private void singleLocalAssign(Name name, String valu) {
|
||||
outi( javascope.getJavaName(name.variable) );
|
||||
if ( name.variable.isupvalue )
|
||||
out( "[0]" );
|
||||
outr( " = "+valu+";");
|
||||
}
|
||||
private void singleLocalDeclareAssign(Name name, String value) {
|
||||
String javaname = javascope.getJavaName(name.variable);
|
||||
if ( name.variable.isupvalue )
|
||||
outl( "final LuaValue[] "+javaname+" = {"+value+"};" );
|
||||
else
|
||||
outl( "LuaValue "+javaname+(value!=null? " = "+value: "")+";" );
|
||||
}
|
||||
public void visit(Break breakstat) {
|
||||
// TODO: wrap in do {} while(false), or add label as nec
|
||||
outl( "break;" );
|
||||
}
|
||||
|
||||
private Writer pushWriter() {
|
||||
Writer x = writer;
|
||||
writer = new CharArrayWriter();
|
||||
return x;
|
||||
}
|
||||
|
||||
private String popWriter(Writer x) {
|
||||
Writer c = writer;
|
||||
writer = x;
|
||||
return c.toString();
|
||||
}
|
||||
|
||||
public String eval(List<Exp> values) {
|
||||
int n = values.size();
|
||||
switch ( n ) {
|
||||
case 0: return "NONE";
|
||||
case 1: return eval(values.get(0));
|
||||
default:
|
||||
Writer x = pushWriter();
|
||||
out( n<=3? "varargsOf(": "varargsOf(new LuaValue[] {" );
|
||||
for ( int i=0; i<n; i++ ) {
|
||||
if ( i>0 ) out( "," );
|
||||
out(eval(values.get(i)));
|
||||
}
|
||||
out( n<=3? ")": "})" );
|
||||
return popWriter(x);
|
||||
}
|
||||
}
|
||||
|
||||
public String eval(Exp exp) {
|
||||
Writer x = pushWriter();
|
||||
exp.accept(this);
|
||||
return popWriter(x);
|
||||
}
|
||||
|
||||
public void visit(BinopExp exp) {
|
||||
switch ( exp.op ) {
|
||||
case Lua.OP_AND:
|
||||
case Lua.OP_OR:
|
||||
out(exp.op==Lua.OP_AND? "(!($b=": "(($b=");
|
||||
exp.lhs.accept(this);
|
||||
out(").toboolean()?$b:");
|
||||
exp.rhs.accept(this);
|
||||
out( ")" );
|
||||
return;
|
||||
|
||||
}
|
||||
exp.lhs.accept(this);
|
||||
switch ( exp.op ) {
|
||||
case Lua.OP_ADD: out(".add"); break;
|
||||
case Lua.OP_SUB: out(".sub"); break;
|
||||
case Lua.OP_MUL: out(".mul"); break;
|
||||
case Lua.OP_DIV: out(".div"); break;
|
||||
case Lua.OP_POW: out(".pow"); break;
|
||||
case Lua.OP_MOD: out(".mod"); break;
|
||||
case Lua.OP_GT: out(".gt"); break;
|
||||
case Lua.OP_GE: out(".ge"); break;
|
||||
case Lua.OP_LT: out(".lt"); break;
|
||||
case Lua.OP_LE: out(".le"); break;
|
||||
case Lua.OP_EQ: out(".eq"); break;
|
||||
case Lua.OP_NEQ: out(".neq"); break;
|
||||
case Lua.OP_CONCAT: out(".concat"); break;
|
||||
default: throw new IllegalStateException("unknown bin op:"+exp.op);
|
||||
}
|
||||
out("(");
|
||||
exp.rhs.accept(this);
|
||||
out(")");
|
||||
}
|
||||
|
||||
public void visit(UnopExp exp) {
|
||||
exp.rhs.accept(this);
|
||||
switch ( exp.op ) {
|
||||
case Lua.OP_NOT: out(".not()"); break;
|
||||
case Lua.OP_LEN: out(".len()"); break;
|
||||
case Lua.OP_UNM: out(".neg()"); break;
|
||||
}
|
||||
}
|
||||
|
||||
public void visit(Constant exp) {
|
||||
switch ( exp.value.type() ) {
|
||||
case LuaValue.TSTRING: {
|
||||
// TODO: non-UTF8 data
|
||||
out( evalStringConstant(exp.value.tojstring()) );
|
||||
break;
|
||||
}
|
||||
case LuaValue.TNIL:
|
||||
out("NIL");
|
||||
break;
|
||||
case LuaValue.TBOOLEAN:
|
||||
out(exp.value.toboolean()? "TRUE": "FALSE");
|
||||
break;
|
||||
case LuaValue.TNUMBER: {
|
||||
out( evalNumberConstant(exp.value.todouble()) );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new IllegalStateException("unknown constant type: "+exp.value.typename());
|
||||
}
|
||||
}
|
||||
|
||||
private String evalStringConstant(String str) {
|
||||
// TODO: quoting, data pooling
|
||||
if ( stringConstants.containsKey(str) )
|
||||
return stringConstants.get(str);
|
||||
String declvalue = quotedStringInitializer(str.getBytes());
|
||||
String javaname = javascope.createConstantName(str);
|
||||
constantDeclarations.add( "static final LuaValue "+javaname+" = valueOf("+declvalue+");" );
|
||||
stringConstants.put(str,javaname);
|
||||
return javaname;
|
||||
}
|
||||
|
||||
private String evalNumberConstant(double value) {
|
||||
if ( value == 0 ) return "ZERO";
|
||||
if ( value == -1 ) return "MINUSONE";
|
||||
if ( value == 1 ) return "ONE";
|
||||
if ( numberConstants.containsKey(value) )
|
||||
return numberConstants.get(value);
|
||||
int ivalue = (int) value;
|
||||
String declvalue = value==ivalue? String.valueOf(ivalue): String.valueOf(value);
|
||||
String javaname = javascope.createConstantName(declvalue);
|
||||
constantDeclarations.add( "static final LuaValue "+javaname+" = valueOf("+declvalue+");" );
|
||||
numberConstants.put(value,javaname);
|
||||
return javaname;
|
||||
}
|
||||
|
||||
public void visit(FieldExp exp) {
|
||||
exp.lhs.accept(this);
|
||||
out(".get("+evalStringConstant(exp.name.name)+")");
|
||||
}
|
||||
|
||||
public void visit(IndexExp exp) {
|
||||
exp.lhs.accept(this);
|
||||
out(".get(");
|
||||
exp.exp.accept(this);
|
||||
out(")");
|
||||
}
|
||||
|
||||
public void visit(NameExp exp) {
|
||||
if ( exp.name.variable.isLocal() ) {
|
||||
out( javascope.getJavaName(exp.name.variable) );
|
||||
if ( exp.name.variable.isupvalue )
|
||||
out( "[0]" );
|
||||
} else {
|
||||
out( "env.get("+evalStringConstant(exp.name.name)+")");
|
||||
}
|
||||
}
|
||||
|
||||
public void visit(ParensExp exp) {
|
||||
exp.exp.accept(this);
|
||||
out(".arg1()");
|
||||
}
|
||||
|
||||
public void visit(VarargsExp exp) {
|
||||
out( "arg" );
|
||||
}
|
||||
|
||||
public void visit(MethodCall exp) {
|
||||
int n = exp.args.exps != null? exp.args.exps.size(): 0;
|
||||
exp.lhs.accept(this);
|
||||
switch ( n ) {
|
||||
case 0:
|
||||
out(".method("+evalStringConstant(exp.name)+")");
|
||||
break;
|
||||
case 1: case 2: case 3:
|
||||
out(".method("+evalStringConstant(exp.name)+",");
|
||||
exp.args.accept(this);
|
||||
out(")");
|
||||
break;
|
||||
default:
|
||||
out(".invokemethod("+evalStringConstant(exp.name)+",varargsOf(new LuaValue[]{");
|
||||
exp.args.accept(this);
|
||||
out("})).arg1()");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void visit(FuncCall exp) {
|
||||
int n = exp.args.exps != null? exp.args.exps.size(): 0;
|
||||
exp.lhs.accept(this);
|
||||
switch ( n ) {
|
||||
case 0: case 1: case 2: case 3:
|
||||
out(".call(");
|
||||
exp.args.accept(this);
|
||||
out(")");
|
||||
break;
|
||||
default:
|
||||
out(".invoke("+eval(exp.args.exps)+").arg1()");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void visit(FuncArgs args) {
|
||||
if ( args.exps != null ) {
|
||||
int n = args.exps.size();
|
||||
for ( int i=0; i<n; i++ ) {
|
||||
if ( i > 0 ) out(",");
|
||||
Exp e = args.exps.get(i);
|
||||
out( eval( e ) );
|
||||
// TODO: arg1(), varargs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void visit(FuncBody body) {
|
||||
javascope = javascope.pushJavaScope(body);
|
||||
int n = javascope.nreturns;
|
||||
int m = body.parlist.names!=null? body.parlist.names.size(): 0;
|
||||
if ( n>=0 && n<=1 && m<=3 && ! body.parlist.isvararg ) {
|
||||
switch ( m ) {
|
||||
case 0:
|
||||
outr("new ZeroArgFunction() {");
|
||||
addindent();
|
||||
outb("public LuaValue call() {");
|
||||
break;
|
||||
case 1:
|
||||
outr("new OneArgFunction() {");
|
||||
addindent();
|
||||
outb("public LuaValue call("
|
||||
+declareArg(body.parlist.names.get(0))+") {");
|
||||
assignArg(body.parlist.names.get(0));
|
||||
break;
|
||||
case 2:
|
||||
outr("new TwoArgFunction() {");
|
||||
addindent();
|
||||
outb("public LuaValue call("
|
||||
+declareArg(body.parlist.names.get(0))+","
|
||||
+declareArg(body.parlist.names.get(1))+") {");
|
||||
assignArg(body.parlist.names.get(0));
|
||||
assignArg(body.parlist.names.get(1));
|
||||
break;
|
||||
case 3:
|
||||
outr("new ThreeArgFunction() {");
|
||||
addindent();
|
||||
outb("public LuaValue call("
|
||||
+declareArg(body.parlist.names.get(0))+","
|
||||
+declareArg(body.parlist.names.get(1))+","
|
||||
+declareArg(body.parlist.names.get(2))+") {");
|
||||
assignArg(body.parlist.names.get(0));
|
||||
assignArg(body.parlist.names.get(1));
|
||||
assignArg(body.parlist.names.get(2));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
outr("new VarArgFunction() {");
|
||||
addindent();
|
||||
outb("public Varargs invoke(Varargs arg) {");
|
||||
for ( int i=0; i<m; i++ ) {
|
||||
Name name = body.parlist.names.get(i);
|
||||
String argname = javascope.getJavaName(name.variable);
|
||||
String value = i>0? "arg.arg("+(i+1)+")": "arg.arg1()";
|
||||
if ( name.variable.isupvalue )
|
||||
outl( "final LuaValue[] "+argname+" = {"+value+"};" );
|
||||
else
|
||||
outl( "LuaValue "+argname+" = "+value+";" );
|
||||
}
|
||||
if ( body.parlist.isvararg && m > 0 )
|
||||
outl( "arg = arg.arglist("+(m+1)+");" );
|
||||
}
|
||||
writeBodyBlock(body.block);
|
||||
oute("}");
|
||||
subindent();
|
||||
outi("}");
|
||||
javascope = javascope.popJavaScope();
|
||||
}
|
||||
|
||||
private String declareArg(Name name) {
|
||||
String argname = javascope.getJavaName(name.variable);
|
||||
return "LuaValue "+argname+(name.variable.isupvalue? "$0": "");
|
||||
}
|
||||
|
||||
private void assignArg(Name name) {
|
||||
if ( name.variable.isupvalue ) {
|
||||
String argname = javascope.getJavaName(name.variable);
|
||||
outl( "final LuaValue[] "+argname+" = {"+argname+"$0};" );
|
||||
}
|
||||
}
|
||||
|
||||
public void visit(FuncCallStat stat) {
|
||||
outl(eval(stat.funccall)+";");
|
||||
}
|
||||
|
||||
public void visit(FuncDef stat) {
|
||||
super.visit(stat);
|
||||
}
|
||||
|
||||
public void visit(LocalFuncDef stat) {
|
||||
String javaname = javascope.getJavaName(stat.name.variable);
|
||||
if ( stat.name.variable.isupvalue )
|
||||
outi("final LuaValue[] "+javaname+" = {");
|
||||
else
|
||||
outi("LuaValue "+javaname+" = ");
|
||||
super.visit(stat);
|
||||
outr( stat.name.variable.isupvalue? "};": ";" );
|
||||
}
|
||||
|
||||
public void visit(NumericFor stat) {
|
||||
String javaname = javascope.getJavaName(stat.name.variable);
|
||||
outi("for ( LuaValue "
|
||||
+javaname+"="+eval(stat.initial)+", "
|
||||
+javaname+"$limit="+eval(stat.limit));
|
||||
String stepname = "ONE";
|
||||
if ( stat.step!=null )
|
||||
out(", "+(stepname=javaname+"$step")+"="+eval(stat.step));
|
||||
outr( "; "
|
||||
+javaname+".testfor_b("+javaname+"$limit,"+stepname+"); "
|
||||
+javaname+"="+javaname+".add("+stepname+") ) {" );
|
||||
addindent();
|
||||
super.visit(stat.block);
|
||||
oute( "}" );
|
||||
}
|
||||
|
||||
private Name tmpJavaVar(String s) {
|
||||
Name n = new Name(s);
|
||||
n.variable = javascope.define(s);
|
||||
return n;
|
||||
}
|
||||
|
||||
public void visit(GenericFor stat) {
|
||||
Name f = tmpJavaVar("f");
|
||||
Name s = tmpJavaVar("s");
|
||||
Name var = tmpJavaVar("var");
|
||||
Name v = tmpJavaVar("v");
|
||||
String javaf = javascope.getJavaName(f.variable);
|
||||
String javas = javascope.getJavaName(s.variable);
|
||||
String javavar = javascope.getJavaName(var.variable);
|
||||
String javav = javascope.getJavaName(v.variable);
|
||||
outl("LuaValue "+javaf+","+javas+","+javavar+";");
|
||||
outl("Varargs "+javav+";");
|
||||
List<Name> fsvar = new ArrayList<Name>();
|
||||
fsvar.add(f);
|
||||
fsvar.add(s);
|
||||
fsvar.add(var);
|
||||
multiAssign(fsvar, stat.exps);
|
||||
|
||||
outb("while (true) {");
|
||||
outl( javav+" = "+javaf+".invoke(varargsOf("+javas+","+javavar+"));");
|
||||
outl( "if (("+javavar+"="+javav+".arg1()).isnil()) break;");
|
||||
singleLocalDeclareAssign(stat.names.get(0),javavar);
|
||||
for ( int i=1, n=stat.names.size(); i<n; i++ )
|
||||
singleLocalDeclareAssign(stat.names.get(i),javav+".arg("+(i+1)+")");
|
||||
super.visit(stat.block);
|
||||
oute("}");
|
||||
}
|
||||
|
||||
public void visit(ParList pars) {
|
||||
super.visit(pars);
|
||||
}
|
||||
|
||||
public void visit(IfThenElse stat) {
|
||||
outb( "if ( "+eval(stat.ifexp)+".toboolean() ) {");
|
||||
super.visit(stat.ifblock);
|
||||
if ( stat.elseifblocks != null )
|
||||
for ( int i=0, n=stat.elseifblocks.size(); i<n; i++ ) {
|
||||
subindent();
|
||||
outl( "} else if ( "+eval(stat.elseifexps.get(i))+".toboolean() ) {");
|
||||
addindent();
|
||||
super.visit(stat.elseifblocks.get(i));
|
||||
}
|
||||
if ( stat.elseblock != null ) {
|
||||
subindent();
|
||||
outl( "} else {");
|
||||
addindent();
|
||||
super.visit( stat.elseblock );
|
||||
}
|
||||
oute( "}" );
|
||||
}
|
||||
|
||||
public void visit(RepeatUntil stat) {
|
||||
outb( "do {");
|
||||
super.visit(stat.block);
|
||||
oute( "} while (!"+eval(stat.exp)+".toboolean());" );
|
||||
}
|
||||
|
||||
public void visit(TableConstructor table) {
|
||||
if ( table.fields == null ) {
|
||||
out("LuaValue.tableOf()");
|
||||
} else {
|
||||
int n = table.fields.size();
|
||||
out("LuaValue.tableOf(new LuaValue[]{");
|
||||
for ( int i=0; i<n; i++ ) {
|
||||
TableField f = table.fields.get(i);
|
||||
if ( f.name == null && f.index == null )
|
||||
continue;
|
||||
if ( f.name != null )
|
||||
out( evalStringConstant(f.name)+"," );
|
||||
else
|
||||
out( eval(f.index)+"," );
|
||||
out( eval(f.rhs)+"," );
|
||||
}
|
||||
out("},new LuaValue[] {");
|
||||
for ( int i=0; i<n; i++ ) {
|
||||
TableField f = table.fields.get(i);
|
||||
if ( f.name == null && f.index == null )
|
||||
out( eval(f.rhs)+"," );
|
||||
}
|
||||
out("})");
|
||||
}
|
||||
}
|
||||
|
||||
public void visit(WhileDo stat) {
|
||||
outb( "while ("+eval(stat.exp)+") {");
|
||||
super.visit(stat.block);
|
||||
oute( "}" );
|
||||
}
|
||||
|
||||
public void visitExps(List<Exp> exps) {
|
||||
super.visitExps(exps);
|
||||
}
|
||||
|
||||
public void visitNames(List<Name> names) {
|
||||
super.visitNames(names);
|
||||
}
|
||||
|
||||
public void visitVars(List<VarExp> vars) {
|
||||
super.visitVars(vars);
|
||||
}
|
||||
}
|
||||
|
||||
private static String quotedStringInitializer(byte[] bytes) {
|
||||
int n = bytes.length;
|
||||
StringBuffer sb = new StringBuffer(n+2);
|
||||
|
||||
// check for characters beyond ascii 128
|
||||
for ( int i=0; i<n; i++ )
|
||||
if (bytes[i]<0) {
|
||||
sb.append( "new byte[]{" );
|
||||
for ( int j=0; j<n; j++ ) {
|
||||
if ( j>0 ) sb.append(",");
|
||||
byte b = bytes[j];
|
||||
switch ( b ) {
|
||||
case '\n': sb.append( "'\\n'" ); break;
|
||||
case '\r': sb.append( "'\\r'" ); break;
|
||||
case '\t': sb.append( "'\\t'" ); break;
|
||||
case '\\': sb.append( "'\\\\'" ); break;
|
||||
default:
|
||||
if ( b >= ' ' ) {
|
||||
sb.append( '\'');
|
||||
sb.append( (char) b );
|
||||
sb.append( '\'');
|
||||
} else {
|
||||
sb.append( String.valueOf((int)b) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
sb.append( "}" );
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
sb.append('"');
|
||||
for ( int i=0; i<n; i++ ) {
|
||||
byte b = bytes[i];
|
||||
switch ( b ) {
|
||||
case '\b': sb.append( "\\b" ); break;
|
||||
case '\f': sb.append( "\\f" ); break;
|
||||
case '\n': sb.append( "\\n" ); break;
|
||||
case '\r': sb.append( "\\r" ); break;
|
||||
case '\t': sb.append( "\\t" ); break;
|
||||
case '"': sb.append( "\\\"" ); break;
|
||||
case '\\': sb.append( "\\\\" ); break;
|
||||
default:
|
||||
if ( b >= ' ' ) {
|
||||
sb.append( (char) b ); break;
|
||||
} else {
|
||||
// convert from UTF-8
|
||||
int u = 0xff & (int) b;
|
||||
if ( u>=0xc0 && i+1<n ) {
|
||||
if ( u>=0xe0 && i+2<n ) {
|
||||
u = ((u & 0xf) << 12) | ((0x3f & bytes[i+1]) << 6) | (0x3f & bytes[i+2]);
|
||||
i+= 2;
|
||||
} else {
|
||||
u = ((u & 0x1f) << 6) | (0x3f & bytes[++i]);
|
||||
}
|
||||
}
|
||||
sb.append( "\\u" );
|
||||
sb.append( Integer.toHexString(0x10000+u).substring(1) );
|
||||
}
|
||||
}
|
||||
}
|
||||
sb.append('"');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
165
src/jse/org/luaj/vm2/lua2java/JavaScope.java
Normal file
165
src/jse/org/luaj/vm2/lua2java/JavaScope.java
Normal file
@@ -0,0 +1,165 @@
|
||||
/*******************************************************************************
|
||||
* 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.lua2java;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.luaj.vm2.Lua;
|
||||
import org.luaj.vm2.ast.Block;
|
||||
import org.luaj.vm2.ast.Chunk;
|
||||
import org.luaj.vm2.ast.FuncBody;
|
||||
import org.luaj.vm2.ast.NameScope;
|
||||
import org.luaj.vm2.ast.Visitor;
|
||||
import org.luaj.vm2.ast.Exp.BinopExp;
|
||||
import org.luaj.vm2.ast.Stat.Return;
|
||||
|
||||
|
||||
public class JavaScope extends NameScope {
|
||||
|
||||
private static final int MAX_CONSTNAME_LEN = 8;
|
||||
public static final Set<String> SPECIALS = new HashSet<String>();
|
||||
|
||||
private static final String[] specials = {
|
||||
// keywords used by our code generator
|
||||
"name", "opcode", "env",
|
||||
|
||||
// java keywords
|
||||
"abstract", "continue", "for", "new", "switch",
|
||||
"assert", "default", "goto", "package", "synchronized",
|
||||
"boolean", "do", "if", "private", "this",
|
||||
"break", "double", "implements", "protected", "throw",
|
||||
"byte", "else", "import", "public", "throws",
|
||||
"case", "enum", "instanceof", "return", "transient",
|
||||
"catch", "extends", "int", "short", "try",
|
||||
"char", "final", "interface", "static", "void",
|
||||
"class", "finally", "long", "strictfp", "volatile",
|
||||
"const", "float", "native", "super", "while",
|
||||
};
|
||||
|
||||
static {
|
||||
for ( int i=0; i<specials.length; i++ )
|
||||
SPECIALS.add(specials[i]);
|
||||
// TODO: add any via reflection from LuaValue
|
||||
}
|
||||
|
||||
public int nreturns;
|
||||
public boolean needsbinoptmp;
|
||||
|
||||
final Set<String> staticnames;
|
||||
final Set<String> javanames = new HashSet<String>();
|
||||
final Map<Object,String> astele2javaname = new HashMap<Object,String>();
|
||||
// final public List<String> tmpvars = new ArrayList<String>();
|
||||
|
||||
private JavaScope(Set<String> staticnames, JavaScope outerScope) {
|
||||
super(outerScope);
|
||||
this.staticnames = staticnames;
|
||||
}
|
||||
|
||||
public static JavaScope newJavaScope(Chunk chunk) {
|
||||
return new JavaScope(new HashSet<String>(), null).initialize(chunk.block, -1);
|
||||
}
|
||||
|
||||
public JavaScope pushJavaScope(FuncBody body) {
|
||||
return new JavaScope(staticnames, this).initialize(body.block, 0);
|
||||
}
|
||||
|
||||
public JavaScope popJavaScope() {
|
||||
return (JavaScope) outerScope;
|
||||
}
|
||||
|
||||
final String getJavaName(NamedVariable nv) {
|
||||
if ( astele2javaname.containsKey(nv) )
|
||||
return astele2javaname.get(nv);
|
||||
return allocateJavaName( nv, nv.name );
|
||||
}
|
||||
|
||||
// public String getTempVar(BinopExp exp) {
|
||||
// return astele2javaname.containsKey(exp)? astele2javaname.get(exp): "$t";
|
||||
// }
|
||||
//
|
||||
// public void allocateTempVar(BinopExp exp) {
|
||||
// tmpvars.add( allocateJavaName( exp, "t" ) );
|
||||
// }
|
||||
//
|
||||
final private String allocateJavaName(Object astele, String proposal) {
|
||||
for ( int i=0; true; i++ ) {
|
||||
String jname = proposal+(i==0? "": "$"+i);
|
||||
if ( ! javanames.contains(jname) && ! SPECIALS.contains(jname) ) {
|
||||
javanames.add(jname);
|
||||
astele2javaname.put(astele,jname);
|
||||
return jname;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String createConstantName(String proposal) {
|
||||
proposal = toLegalJavaName(proposal);
|
||||
for ( int i=0; true; i++ ) {
|
||||
String jname = proposal+(i==0? "": "$"+i);
|
||||
if ( ! javanames.contains(jname) && ! SPECIALS.contains(jname) && !staticnames.contains(jname) ) {
|
||||
javanames.add(jname);
|
||||
staticnames.add(jname);
|
||||
return jname;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String toLegalJavaName(String string) {
|
||||
String better = string.replaceAll("[^\\w]", "_");
|
||||
if ( better.length() > MAX_CONSTNAME_LEN )
|
||||
better = better.substring(0,MAX_CONSTNAME_LEN);
|
||||
// if ( !Character.isJavaIdentifierStart( better.charAt(0) ) )
|
||||
// better = "_"+better;
|
||||
return "$"+better;
|
||||
}
|
||||
|
||||
private JavaScope initialize(Block block, int nreturns) {
|
||||
NewScopeVisitor v = new NewScopeVisitor(nreturns);
|
||||
block.accept( v );
|
||||
this.nreturns = v.nreturns;
|
||||
this.needsbinoptmp = v.needsbinoptmp;
|
||||
return this;
|
||||
}
|
||||
|
||||
class NewScopeVisitor extends Visitor {
|
||||
int nreturns = 0;
|
||||
boolean needsbinoptmp = false;
|
||||
NewScopeVisitor(int nreturns) {
|
||||
this.nreturns = nreturns;
|
||||
}
|
||||
public void visit(FuncBody body) {}
|
||||
public void visit(Return s) {
|
||||
int n = s.nreturns();
|
||||
nreturns = (nreturns<0||n<0? -1: Math.max(n,nreturns));
|
||||
}
|
||||
public void visit(BinopExp exp) {
|
||||
switch ( exp.op ) {
|
||||
case Lua.OP_AND: case Lua.OP_OR:
|
||||
needsbinoptmp = true;
|
||||
break;
|
||||
}
|
||||
super.visit(exp);
|
||||
}
|
||||
}
|
||||
}
|
||||
1641
src/jse/org/luaj/vm2/parser/LuaParser.java
Normal file
1641
src/jse/org/luaj/vm2/parser/LuaParser.java
Normal file
File diff suppressed because it is too large
Load Diff
225
src/jse/org/luaj/vm2/parser/LuaParserConstants.java
Normal file
225
src/jse/org/luaj/vm2/parser/LuaParserConstants.java
Normal file
@@ -0,0 +1,225 @@
|
||||
/* Generated By:JavaCC: Do not edit this line. LuaParserConstants.java */
|
||||
package org.luaj.vm2.parser;
|
||||
|
||||
|
||||
/**
|
||||
* Token literal values and constants.
|
||||
* Generated by org.javacc.parser.OtherFilesGen#start()
|
||||
*/
|
||||
public interface LuaParserConstants {
|
||||
|
||||
/** End of File. */
|
||||
int EOF = 0;
|
||||
/** RegularExpression Id. */
|
||||
int COMMENT = 17;
|
||||
/** RegularExpression Id. */
|
||||
int LONGCOMMENT0 = 18;
|
||||
/** RegularExpression Id. */
|
||||
int LONGCOMMENT1 = 19;
|
||||
/** RegularExpression Id. */
|
||||
int LONGCOMMENT2 = 20;
|
||||
/** RegularExpression Id. */
|
||||
int LONGCOMMENT3 = 21;
|
||||
/** RegularExpression Id. */
|
||||
int LONGCOMMENTN = 22;
|
||||
/** RegularExpression Id. */
|
||||
int LONGSTRING0 = 23;
|
||||
/** RegularExpression Id. */
|
||||
int LONGSTRING1 = 24;
|
||||
/** RegularExpression Id. */
|
||||
int LONGSTRING2 = 25;
|
||||
/** RegularExpression Id. */
|
||||
int LONGSTRING3 = 26;
|
||||
/** RegularExpression Id. */
|
||||
int LONGSTRINGN = 27;
|
||||
/** RegularExpression Id. */
|
||||
int AND = 29;
|
||||
/** RegularExpression Id. */
|
||||
int BREAK = 30;
|
||||
/** RegularExpression Id. */
|
||||
int DO = 31;
|
||||
/** RegularExpression Id. */
|
||||
int ELSE = 32;
|
||||
/** RegularExpression Id. */
|
||||
int ELSEIF = 33;
|
||||
/** RegularExpression Id. */
|
||||
int END = 34;
|
||||
/** RegularExpression Id. */
|
||||
int FALSE = 35;
|
||||
/** RegularExpression Id. */
|
||||
int FOR = 36;
|
||||
/** RegularExpression Id. */
|
||||
int FUNCTION = 37;
|
||||
/** RegularExpression Id. */
|
||||
int IF = 38;
|
||||
/** RegularExpression Id. */
|
||||
int IN = 39;
|
||||
/** RegularExpression Id. */
|
||||
int LOCAL = 40;
|
||||
/** RegularExpression Id. */
|
||||
int NIL = 41;
|
||||
/** RegularExpression Id. */
|
||||
int NOT = 42;
|
||||
/** RegularExpression Id. */
|
||||
int OR = 43;
|
||||
/** RegularExpression Id. */
|
||||
int RETURN = 44;
|
||||
/** RegularExpression Id. */
|
||||
int REPEAT = 45;
|
||||
/** RegularExpression Id. */
|
||||
int THEN = 46;
|
||||
/** RegularExpression Id. */
|
||||
int TRUE = 47;
|
||||
/** RegularExpression Id. */
|
||||
int UNTIL = 48;
|
||||
/** RegularExpression Id. */
|
||||
int WHILE = 49;
|
||||
/** RegularExpression Id. */
|
||||
int NAME = 50;
|
||||
/** RegularExpression Id. */
|
||||
int NUMBER = 51;
|
||||
/** RegularExpression Id. */
|
||||
int FLOAT = 52;
|
||||
/** RegularExpression Id. */
|
||||
int DIGIT = 53;
|
||||
/** RegularExpression Id. */
|
||||
int EXP = 54;
|
||||
/** RegularExpression Id. */
|
||||
int HEX = 55;
|
||||
/** RegularExpression Id. */
|
||||
int HEXDIGIT = 56;
|
||||
/** RegularExpression Id. */
|
||||
int STRING = 57;
|
||||
/** RegularExpression Id. */
|
||||
int CHARSTRING = 58;
|
||||
/** RegularExpression Id. */
|
||||
int QUOTED = 59;
|
||||
/** RegularExpression Id. */
|
||||
int DECIMAL = 60;
|
||||
/** RegularExpression Id. */
|
||||
int UNICODE = 61;
|
||||
/** RegularExpression Id. */
|
||||
int CHAR = 62;
|
||||
/** RegularExpression Id. */
|
||||
int LF = 63;
|
||||
|
||||
/** Lexical state. */
|
||||
int DEFAULT = 0;
|
||||
/** Lexical state. */
|
||||
int IN_COMMENT = 1;
|
||||
/** Lexical state. */
|
||||
int IN_LC0 = 2;
|
||||
/** Lexical state. */
|
||||
int IN_LC1 = 3;
|
||||
/** Lexical state. */
|
||||
int IN_LC2 = 4;
|
||||
/** Lexical state. */
|
||||
int IN_LC3 = 5;
|
||||
/** Lexical state. */
|
||||
int IN_LCN = 6;
|
||||
/** Lexical state. */
|
||||
int IN_LS0 = 7;
|
||||
/** Lexical state. */
|
||||
int IN_LS1 = 8;
|
||||
/** Lexical state. */
|
||||
int IN_LS2 = 9;
|
||||
/** Lexical state. */
|
||||
int IN_LS3 = 10;
|
||||
/** Lexical state. */
|
||||
int IN_LSN = 11;
|
||||
|
||||
/** Literal token values. */
|
||||
String[] tokenImage = {
|
||||
"<EOF>",
|
||||
"\" \"",
|
||||
"\"\\t\"",
|
||||
"\"\\n\"",
|
||||
"\"\\r\"",
|
||||
"\"\\f\"",
|
||||
"\"--[[\"",
|
||||
"\"--[=[\"",
|
||||
"\"--[==[\"",
|
||||
"\"--[===[\"",
|
||||
"<token of kind 10>",
|
||||
"\"[[\"",
|
||||
"\"[=[\"",
|
||||
"\"[==[\"",
|
||||
"\"[===[\"",
|
||||
"<token of kind 15>",
|
||||
"\"--\"",
|
||||
"<COMMENT>",
|
||||
"\"]]\"",
|
||||
"\"]=]\"",
|
||||
"\"]==]\"",
|
||||
"\"]===]\"",
|
||||
"<LONGCOMMENTN>",
|
||||
"\"]]\"",
|
||||
"\"]=]\"",
|
||||
"\"]==]\"",
|
||||
"\"]===]\"",
|
||||
"<LONGSTRINGN>",
|
||||
"<token of kind 28>",
|
||||
"\"and\"",
|
||||
"\"break\"",
|
||||
"\"do\"",
|
||||
"\"else\"",
|
||||
"\"elseif\"",
|
||||
"\"end\"",
|
||||
"\"false\"",
|
||||
"\"for\"",
|
||||
"\"function\"",
|
||||
"\"if\"",
|
||||
"\"in\"",
|
||||
"\"local\"",
|
||||
"\"nil\"",
|
||||
"\"not\"",
|
||||
"\"or\"",
|
||||
"\"return\"",
|
||||
"\"repeat\"",
|
||||
"\"then\"",
|
||||
"\"true\"",
|
||||
"\"until\"",
|
||||
"\"while\"",
|
||||
"<NAME>",
|
||||
"<NUMBER>",
|
||||
"<FLOAT>",
|
||||
"<DIGIT>",
|
||||
"<EXP>",
|
||||
"<HEX>",
|
||||
"<HEXDIGIT>",
|
||||
"<STRING>",
|
||||
"<CHARSTRING>",
|
||||
"<QUOTED>",
|
||||
"<DECIMAL>",
|
||||
"<UNICODE>",
|
||||
"<CHAR>",
|
||||
"<LF>",
|
||||
"\";\"",
|
||||
"\"=\"",
|
||||
"\",\"",
|
||||
"\".\"",
|
||||
"\":\"",
|
||||
"\"(\"",
|
||||
"\")\"",
|
||||
"\"[\"",
|
||||
"\"]\"",
|
||||
"\"...\"",
|
||||
"\"{\"",
|
||||
"\"}\"",
|
||||
"\"+\"",
|
||||
"\"-\"",
|
||||
"\"*\"",
|
||||
"\"/\"",
|
||||
"\"^\"",
|
||||
"\"%\"",
|
||||
"\"..\"",
|
||||
"\"<\"",
|
||||
"\"<=\"",
|
||||
"\">\"",
|
||||
"\">=\"",
|
||||
"\"==\"",
|
||||
"\"~=\"",
|
||||
"\"#\"",
|
||||
};
|
||||
|
||||
}
|
||||
2018
src/jse/org/luaj/vm2/parser/LuaParserTokenManager.java
Normal file
2018
src/jse/org/luaj/vm2/parser/LuaParserTokenManager.java
Normal file
File diff suppressed because it is too large
Load Diff
187
src/jse/org/luaj/vm2/parser/ParseException.java
Normal file
187
src/jse/org/luaj/vm2/parser/ParseException.java
Normal file
@@ -0,0 +1,187 @@
|
||||
/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 5.0 */
|
||||
/* JavaCCOptions:KEEP_LINE_COL=null */
|
||||
package org.luaj.vm2.parser;
|
||||
|
||||
/**
|
||||
* This exception is thrown when parse errors are encountered.
|
||||
* You can explicitly create objects of this exception type by
|
||||
* calling the method generateParseException in the generated
|
||||
* parser.
|
||||
*
|
||||
* You can modify this class to customize your error reporting
|
||||
* mechanisms so long as you retain the public fields.
|
||||
*/
|
||||
public class ParseException extends Exception {
|
||||
|
||||
/**
|
||||
* The version identifier for this Serializable class.
|
||||
* Increment only if the <i>serialized</i> form of the
|
||||
* class changes.
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* This constructor is used by the method "generateParseException"
|
||||
* in the generated parser. Calling this constructor generates
|
||||
* a new object of this type with the fields "currentToken",
|
||||
* "expectedTokenSequences", and "tokenImage" set.
|
||||
*/
|
||||
public ParseException(Token currentTokenVal,
|
||||
int[][] expectedTokenSequencesVal,
|
||||
String[] tokenImageVal
|
||||
)
|
||||
{
|
||||
super(initialise(currentTokenVal, expectedTokenSequencesVal, tokenImageVal));
|
||||
currentToken = currentTokenVal;
|
||||
expectedTokenSequences = expectedTokenSequencesVal;
|
||||
tokenImage = tokenImageVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* The following constructors are for use by you for whatever
|
||||
* purpose you can think of. Constructing the exception in this
|
||||
* manner makes the exception behave in the normal way - i.e., as
|
||||
* documented in the class "Throwable". The fields "errorToken",
|
||||
* "expectedTokenSequences", and "tokenImage" do not contain
|
||||
* relevant information. The JavaCC generated code does not use
|
||||
* these constructors.
|
||||
*/
|
||||
|
||||
public ParseException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/** Constructor with message. */
|
||||
public ParseException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is the last token that has been consumed successfully. If
|
||||
* this object has been created due to a parse error, the token
|
||||
* followng this token will (therefore) be the first error token.
|
||||
*/
|
||||
public Token currentToken;
|
||||
|
||||
/**
|
||||
* Each entry in this array is an array of integers. Each array
|
||||
* of integers represents a sequence of tokens (by their ordinal
|
||||
* values) that is expected at this point of the parse.
|
||||
*/
|
||||
public int[][] expectedTokenSequences;
|
||||
|
||||
/**
|
||||
* This is a reference to the "tokenImage" array of the generated
|
||||
* parser within which the parse error occurred. This array is
|
||||
* defined in the generated ...Constants interface.
|
||||
*/
|
||||
public String[] tokenImage;
|
||||
|
||||
/**
|
||||
* It uses "currentToken" and "expectedTokenSequences" to generate a parse
|
||||
* error message and returns it. If this object has been created
|
||||
* due to a parse error, and you do not catch it (it gets thrown
|
||||
* from the parser) the correct error message
|
||||
* gets displayed.
|
||||
*/
|
||||
private static String initialise(Token currentToken,
|
||||
int[][] expectedTokenSequences,
|
||||
String[] tokenImage) {
|
||||
String eol = System.getProperty("line.separator", "\n");
|
||||
StringBuffer expected = new StringBuffer();
|
||||
int maxSize = 0;
|
||||
for (int i = 0; i < expectedTokenSequences.length; i++) {
|
||||
if (maxSize < expectedTokenSequences[i].length) {
|
||||
maxSize = expectedTokenSequences[i].length;
|
||||
}
|
||||
for (int j = 0; j < expectedTokenSequences[i].length; j++) {
|
||||
expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' ');
|
||||
}
|
||||
if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
|
||||
expected.append("...");
|
||||
}
|
||||
expected.append(eol).append(" ");
|
||||
}
|
||||
String retval = "Encountered \"";
|
||||
Token tok = currentToken.next;
|
||||
for (int i = 0; i < maxSize; i++) {
|
||||
if (i != 0) retval += " ";
|
||||
if (tok.kind == 0) {
|
||||
retval += tokenImage[0];
|
||||
break;
|
||||
}
|
||||
retval += " " + tokenImage[tok.kind];
|
||||
retval += " \"";
|
||||
retval += add_escapes(tok.image);
|
||||
retval += " \"";
|
||||
tok = tok.next;
|
||||
}
|
||||
retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
|
||||
retval += "." + eol;
|
||||
if (expectedTokenSequences.length == 1) {
|
||||
retval += "Was expecting:" + eol + " ";
|
||||
} else {
|
||||
retval += "Was expecting one of:" + eol + " ";
|
||||
}
|
||||
retval += expected.toString();
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* The end of line string for this machine.
|
||||
*/
|
||||
protected String eol = System.getProperty("line.separator", "\n");
|
||||
|
||||
/**
|
||||
* Used to convert raw characters to their escaped version
|
||||
* when these raw version cannot be used as part of an ASCII
|
||||
* string literal.
|
||||
*/
|
||||
static String add_escapes(String str) {
|
||||
StringBuffer retval = new StringBuffer();
|
||||
char ch;
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
switch (str.charAt(i))
|
||||
{
|
||||
case 0 :
|
||||
continue;
|
||||
case '\b':
|
||||
retval.append("\\b");
|
||||
continue;
|
||||
case '\t':
|
||||
retval.append("\\t");
|
||||
continue;
|
||||
case '\n':
|
||||
retval.append("\\n");
|
||||
continue;
|
||||
case '\f':
|
||||
retval.append("\\f");
|
||||
continue;
|
||||
case '\r':
|
||||
retval.append("\\r");
|
||||
continue;
|
||||
case '\"':
|
||||
retval.append("\\\"");
|
||||
continue;
|
||||
case '\'':
|
||||
retval.append("\\\'");
|
||||
continue;
|
||||
case '\\':
|
||||
retval.append("\\\\");
|
||||
continue;
|
||||
default:
|
||||
if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
|
||||
String s = "0000" + Integer.toString(ch, 16);
|
||||
retval.append("\\u" + s.substring(s.length() - 4, s.length()));
|
||||
} else {
|
||||
retval.append(ch);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return retval.toString();
|
||||
}
|
||||
|
||||
}
|
||||
/* JavaCC - OriginalChecksum=ef246095a930e4915c0d4bbf4c9880ad (do not edit this line) */
|
||||
469
src/jse/org/luaj/vm2/parser/SimpleCharStream.java
Normal file
469
src/jse/org/luaj/vm2/parser/SimpleCharStream.java
Normal file
@@ -0,0 +1,469 @@
|
||||
/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 5.0 */
|
||||
/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
|
||||
package org.luaj.vm2.parser;
|
||||
|
||||
/**
|
||||
* An implementation of interface CharStream, where the stream is assumed to
|
||||
* contain only ASCII characters (without unicode processing).
|
||||
*/
|
||||
|
||||
public class SimpleCharStream
|
||||
{
|
||||
/** Whether parser is static. */
|
||||
public static final boolean staticFlag = false;
|
||||
int bufsize;
|
||||
int available;
|
||||
int tokenBegin;
|
||||
/** Position in buffer. */
|
||||
public int bufpos = -1;
|
||||
protected int bufline[];
|
||||
protected int bufcolumn[];
|
||||
|
||||
protected int column = 0;
|
||||
protected int line = 1;
|
||||
|
||||
protected boolean prevCharIsCR = false;
|
||||
protected boolean prevCharIsLF = false;
|
||||
|
||||
protected java.io.Reader inputStream;
|
||||
|
||||
protected char[] buffer;
|
||||
protected int maxNextCharInd = 0;
|
||||
protected int inBuf = 0;
|
||||
protected int tabSize = 8;
|
||||
|
||||
protected void setTabSize(int i) { tabSize = i; }
|
||||
protected int getTabSize(int i) { return tabSize; }
|
||||
|
||||
|
||||
protected void ExpandBuff(boolean wrapAround)
|
||||
{
|
||||
char[] newbuffer = new char[bufsize + 2048];
|
||||
int newbufline[] = new int[bufsize + 2048];
|
||||
int newbufcolumn[] = new int[bufsize + 2048];
|
||||
|
||||
try
|
||||
{
|
||||
if (wrapAround)
|
||||
{
|
||||
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
|
||||
System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
|
||||
buffer = newbuffer;
|
||||
|
||||
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
|
||||
System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
|
||||
bufline = newbufline;
|
||||
|
||||
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
|
||||
System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
|
||||
bufcolumn = newbufcolumn;
|
||||
|
||||
maxNextCharInd = (bufpos += (bufsize - tokenBegin));
|
||||
}
|
||||
else
|
||||
{
|
||||
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
|
||||
buffer = newbuffer;
|
||||
|
||||
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
|
||||
bufline = newbufline;
|
||||
|
||||
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
|
||||
bufcolumn = newbufcolumn;
|
||||
|
||||
maxNextCharInd = (bufpos -= tokenBegin);
|
||||
}
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
throw new Error(t.getMessage());
|
||||
}
|
||||
|
||||
|
||||
bufsize += 2048;
|
||||
available = bufsize;
|
||||
tokenBegin = 0;
|
||||
}
|
||||
|
||||
protected void FillBuff() throws java.io.IOException
|
||||
{
|
||||
if (maxNextCharInd == available)
|
||||
{
|
||||
if (available == bufsize)
|
||||
{
|
||||
if (tokenBegin > 2048)
|
||||
{
|
||||
bufpos = maxNextCharInd = 0;
|
||||
available = tokenBegin;
|
||||
}
|
||||
else if (tokenBegin < 0)
|
||||
bufpos = maxNextCharInd = 0;
|
||||
else
|
||||
ExpandBuff(false);
|
||||
}
|
||||
else if (available > tokenBegin)
|
||||
available = bufsize;
|
||||
else if ((tokenBegin - available) < 2048)
|
||||
ExpandBuff(true);
|
||||
else
|
||||
available = tokenBegin;
|
||||
}
|
||||
|
||||
int i;
|
||||
try {
|
||||
if ((i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd)) == -1)
|
||||
{
|
||||
inputStream.close();
|
||||
throw new java.io.IOException();
|
||||
}
|
||||
else
|
||||
maxNextCharInd += i;
|
||||
return;
|
||||
}
|
||||
catch(java.io.IOException e) {
|
||||
--bufpos;
|
||||
backup(0);
|
||||
if (tokenBegin == -1)
|
||||
tokenBegin = bufpos;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/** Start. */
|
||||
public char BeginToken() throws java.io.IOException
|
||||
{
|
||||
tokenBegin = -1;
|
||||
char c = readChar();
|
||||
tokenBegin = bufpos;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
protected void UpdateLineColumn(char c)
|
||||
{
|
||||
column++;
|
||||
|
||||
if (prevCharIsLF)
|
||||
{
|
||||
prevCharIsLF = false;
|
||||
line += (column = 1);
|
||||
}
|
||||
else if (prevCharIsCR)
|
||||
{
|
||||
prevCharIsCR = false;
|
||||
if (c == '\n')
|
||||
{
|
||||
prevCharIsLF = true;
|
||||
}
|
||||
else
|
||||
line += (column = 1);
|
||||
}
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '\r' :
|
||||
prevCharIsCR = true;
|
||||
break;
|
||||
case '\n' :
|
||||
prevCharIsLF = true;
|
||||
break;
|
||||
case '\t' :
|
||||
column--;
|
||||
column += (tabSize - (column % tabSize));
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
bufline[bufpos] = line;
|
||||
bufcolumn[bufpos] = column;
|
||||
}
|
||||
|
||||
/** Read a character. */
|
||||
public char readChar() throws java.io.IOException
|
||||
{
|
||||
if (inBuf > 0)
|
||||
{
|
||||
--inBuf;
|
||||
|
||||
if (++bufpos == bufsize)
|
||||
bufpos = 0;
|
||||
|
||||
return buffer[bufpos];
|
||||
}
|
||||
|
||||
if (++bufpos >= maxNextCharInd)
|
||||
FillBuff();
|
||||
|
||||
char c = buffer[bufpos];
|
||||
|
||||
UpdateLineColumn(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @see #getEndColumn
|
||||
*/
|
||||
|
||||
public int getColumn() {
|
||||
return bufcolumn[bufpos];
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @see #getEndLine
|
||||
*/
|
||||
|
||||
public int getLine() {
|
||||
return bufline[bufpos];
|
||||
}
|
||||
|
||||
/** Get token end column number. */
|
||||
public int getEndColumn() {
|
||||
return bufcolumn[bufpos];
|
||||
}
|
||||
|
||||
/** Get token end line number. */
|
||||
public int getEndLine() {
|
||||
return bufline[bufpos];
|
||||
}
|
||||
|
||||
/** Get token beginning column number. */
|
||||
public int getBeginColumn() {
|
||||
return bufcolumn[tokenBegin];
|
||||
}
|
||||
|
||||
/** Get token beginning line number. */
|
||||
public int getBeginLine() {
|
||||
return bufline[tokenBegin];
|
||||
}
|
||||
|
||||
/** Backup a number of characters. */
|
||||
public void backup(int amount) {
|
||||
|
||||
inBuf += amount;
|
||||
if ((bufpos -= amount) < 0)
|
||||
bufpos += bufsize;
|
||||
}
|
||||
|
||||
/** Constructor. */
|
||||
public SimpleCharStream(java.io.Reader dstream, int startline,
|
||||
int startcolumn, int buffersize)
|
||||
{
|
||||
inputStream = dstream;
|
||||
line = startline;
|
||||
column = startcolumn - 1;
|
||||
|
||||
available = bufsize = buffersize;
|
||||
buffer = new char[buffersize];
|
||||
bufline = new int[buffersize];
|
||||
bufcolumn = new int[buffersize];
|
||||
}
|
||||
|
||||
/** Constructor. */
|
||||
public SimpleCharStream(java.io.Reader dstream, int startline,
|
||||
int startcolumn)
|
||||
{
|
||||
this(dstream, startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
/** Constructor. */
|
||||
public SimpleCharStream(java.io.Reader dstream)
|
||||
{
|
||||
this(dstream, 1, 1, 4096);
|
||||
}
|
||||
|
||||
/** Reinitialise. */
|
||||
public void ReInit(java.io.Reader dstream, int startline,
|
||||
int startcolumn, int buffersize)
|
||||
{
|
||||
inputStream = dstream;
|
||||
line = startline;
|
||||
column = startcolumn - 1;
|
||||
|
||||
if (buffer == null || buffersize != buffer.length)
|
||||
{
|
||||
available = bufsize = buffersize;
|
||||
buffer = new char[buffersize];
|
||||
bufline = new int[buffersize];
|
||||
bufcolumn = new int[buffersize];
|
||||
}
|
||||
prevCharIsLF = prevCharIsCR = false;
|
||||
tokenBegin = inBuf = maxNextCharInd = 0;
|
||||
bufpos = -1;
|
||||
}
|
||||
|
||||
/** Reinitialise. */
|
||||
public void ReInit(java.io.Reader dstream, int startline,
|
||||
int startcolumn)
|
||||
{
|
||||
ReInit(dstream, startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
/** Reinitialise. */
|
||||
public void ReInit(java.io.Reader dstream)
|
||||
{
|
||||
ReInit(dstream, 1, 1, 4096);
|
||||
}
|
||||
/** Constructor. */
|
||||
public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
|
||||
int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
|
||||
{
|
||||
this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
|
||||
}
|
||||
|
||||
/** Constructor. */
|
||||
public SimpleCharStream(java.io.InputStream dstream, int startline,
|
||||
int startcolumn, int buffersize)
|
||||
{
|
||||
this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
|
||||
}
|
||||
|
||||
/** Constructor. */
|
||||
public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
|
||||
int startcolumn) throws java.io.UnsupportedEncodingException
|
||||
{
|
||||
this(dstream, encoding, startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
/** Constructor. */
|
||||
public SimpleCharStream(java.io.InputStream dstream, int startline,
|
||||
int startcolumn)
|
||||
{
|
||||
this(dstream, startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
/** Constructor. */
|
||||
public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
|
||||
{
|
||||
this(dstream, encoding, 1, 1, 4096);
|
||||
}
|
||||
|
||||
/** Constructor. */
|
||||
public SimpleCharStream(java.io.InputStream dstream)
|
||||
{
|
||||
this(dstream, 1, 1, 4096);
|
||||
}
|
||||
|
||||
/** Reinitialise. */
|
||||
public void ReInit(java.io.InputStream dstream, String encoding, int startline,
|
||||
int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
|
||||
{
|
||||
ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
|
||||
}
|
||||
|
||||
/** Reinitialise. */
|
||||
public void ReInit(java.io.InputStream dstream, int startline,
|
||||
int startcolumn, int buffersize)
|
||||
{
|
||||
ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
|
||||
}
|
||||
|
||||
/** Reinitialise. */
|
||||
public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
|
||||
{
|
||||
ReInit(dstream, encoding, 1, 1, 4096);
|
||||
}
|
||||
|
||||
/** Reinitialise. */
|
||||
public void ReInit(java.io.InputStream dstream)
|
||||
{
|
||||
ReInit(dstream, 1, 1, 4096);
|
||||
}
|
||||
/** Reinitialise. */
|
||||
public void ReInit(java.io.InputStream dstream, String encoding, int startline,
|
||||
int startcolumn) throws java.io.UnsupportedEncodingException
|
||||
{
|
||||
ReInit(dstream, encoding, startline, startcolumn, 4096);
|
||||
}
|
||||
/** Reinitialise. */
|
||||
public void ReInit(java.io.InputStream dstream, int startline,
|
||||
int startcolumn)
|
||||
{
|
||||
ReInit(dstream, startline, startcolumn, 4096);
|
||||
}
|
||||
/** Get token literal value. */
|
||||
public String GetImage()
|
||||
{
|
||||
if (bufpos >= tokenBegin)
|
||||
return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
|
||||
else
|
||||
return new String(buffer, tokenBegin, bufsize - tokenBegin) +
|
||||
new String(buffer, 0, bufpos + 1);
|
||||
}
|
||||
|
||||
/** Get the suffix. */
|
||||
public char[] GetSuffix(int len)
|
||||
{
|
||||
char[] ret = new char[len];
|
||||
|
||||
if ((bufpos + 1) >= len)
|
||||
System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
|
||||
else
|
||||
{
|
||||
System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
|
||||
len - bufpos - 1);
|
||||
System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Reset buffer when finished. */
|
||||
public void Done()
|
||||
{
|
||||
buffer = null;
|
||||
bufline = null;
|
||||
bufcolumn = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to adjust line and column numbers for the start of a token.
|
||||
*/
|
||||
public void adjustBeginLineColumn(int newLine, int newCol)
|
||||
{
|
||||
int start = tokenBegin;
|
||||
int len;
|
||||
|
||||
if (bufpos >= tokenBegin)
|
||||
{
|
||||
len = bufpos - tokenBegin + inBuf + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = bufsize - tokenBegin + bufpos + 1 + inBuf;
|
||||
}
|
||||
|
||||
int i = 0, j = 0, k = 0;
|
||||
int nextColDiff = 0, columnDiff = 0;
|
||||
|
||||
while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
|
||||
{
|
||||
bufline[j] = newLine;
|
||||
nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
|
||||
bufcolumn[j] = newCol + columnDiff;
|
||||
columnDiff = nextColDiff;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i < len)
|
||||
{
|
||||
bufline[j] = newLine++;
|
||||
bufcolumn[j] = newCol + columnDiff;
|
||||
|
||||
while (i++ < len)
|
||||
{
|
||||
if (bufline[j = start % bufsize] != bufline[++start % bufsize])
|
||||
bufline[j] = newLine++;
|
||||
else
|
||||
bufline[j] = newLine;
|
||||
}
|
||||
}
|
||||
|
||||
line = bufline[j];
|
||||
column = bufcolumn[j];
|
||||
}
|
||||
|
||||
}
|
||||
/* JavaCC - OriginalChecksum=ab0c629eabd887d4c88cec51eb5e6477 (do not edit this line) */
|
||||
131
src/jse/org/luaj/vm2/parser/Token.java
Normal file
131
src/jse/org/luaj/vm2/parser/Token.java
Normal file
@@ -0,0 +1,131 @@
|
||||
/* Generated By:JavaCC: Do not edit this line. Token.java Version 5.0 */
|
||||
/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
|
||||
package org.luaj.vm2.parser;
|
||||
|
||||
/**
|
||||
* Describes the input token stream.
|
||||
*/
|
||||
|
||||
public class Token implements java.io.Serializable {
|
||||
|
||||
/**
|
||||
* The version identifier for this Serializable class.
|
||||
* Increment only if the <i>serialized</i> form of the
|
||||
* class changes.
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* An integer that describes the kind of this token. This numbering
|
||||
* system is determined by JavaCCParser, and a table of these numbers is
|
||||
* stored in the file ...Constants.java.
|
||||
*/
|
||||
public int kind;
|
||||
|
||||
/** The line number of the first character of this Token. */
|
||||
public int beginLine;
|
||||
/** The column number of the first character of this Token. */
|
||||
public int beginColumn;
|
||||
/** The line number of the last character of this Token. */
|
||||
public int endLine;
|
||||
/** The column number of the last character of this Token. */
|
||||
public int endColumn;
|
||||
|
||||
/**
|
||||
* The string image of the token.
|
||||
*/
|
||||
public String image;
|
||||
|
||||
/**
|
||||
* A reference to the next regular (non-special) token from the input
|
||||
* stream. If this is the last token from the input stream, or if the
|
||||
* token manager has not read tokens beyond this one, this field is
|
||||
* set to null. This is true only if this token is also a regular
|
||||
* token. Otherwise, see below for a description of the contents of
|
||||
* this field.
|
||||
*/
|
||||
public Token next;
|
||||
|
||||
/**
|
||||
* This field is used to access special tokens that occur prior to this
|
||||
* token, but after the immediately preceding regular (non-special) token.
|
||||
* If there are no such special tokens, this field is set to null.
|
||||
* When there are more than one such special token, this field refers
|
||||
* to the last of these special tokens, which in turn refers to the next
|
||||
* previous special token through its specialToken field, and so on
|
||||
* until the first special token (whose specialToken field is null).
|
||||
* The next fields of special tokens refer to other special tokens that
|
||||
* immediately follow it (without an intervening regular token). If there
|
||||
* is no such token, this field is null.
|
||||
*/
|
||||
public Token specialToken;
|
||||
|
||||
/**
|
||||
* An optional attribute value of the Token.
|
||||
* Tokens which are not used as syntactic sugar will often contain
|
||||
* meaningful values that will be used later on by the compiler or
|
||||
* interpreter. This attribute value is often different from the image.
|
||||
* Any subclass of Token that actually wants to return a non-null value can
|
||||
* override this method as appropriate.
|
||||
*/
|
||||
public Object getValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* No-argument constructor
|
||||
*/
|
||||
public Token() {}
|
||||
|
||||
/**
|
||||
* Constructs a new token for the specified Image.
|
||||
*/
|
||||
public Token(int kind)
|
||||
{
|
||||
this(kind, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new token for the specified Image and Kind.
|
||||
*/
|
||||
public Token(int kind, String image)
|
||||
{
|
||||
this.kind = kind;
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the image.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new Token object, by default. However, if you want, you
|
||||
* can create and return subclass objects based on the value of ofKind.
|
||||
* Simply add the cases to the switch for all those special cases.
|
||||
* For example, if you have a subclass of Token called IDToken that
|
||||
* you want to create if ofKind is ID, simply add something like :
|
||||
*
|
||||
* case MyParserConstants.ID : return new IDToken(ofKind, image);
|
||||
*
|
||||
* to the following switch statement. Then you can cast matchedToken
|
||||
* variable to the appropriate type and use sit in your lexical actions.
|
||||
*/
|
||||
public static Token newToken(int ofKind, String image)
|
||||
{
|
||||
switch(ofKind)
|
||||
{
|
||||
default : return new Token(ofKind, image);
|
||||
}
|
||||
}
|
||||
|
||||
public static Token newToken(int ofKind)
|
||||
{
|
||||
return newToken(ofKind, null);
|
||||
}
|
||||
|
||||
}
|
||||
/* JavaCC - OriginalChecksum=70d73add5771158f10d1ae81755e7cfc (do not edit this line) */
|
||||
147
src/jse/org/luaj/vm2/parser/TokenMgrError.java
Normal file
147
src/jse/org/luaj/vm2/parser/TokenMgrError.java
Normal file
@@ -0,0 +1,147 @@
|
||||
/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 5.0 */
|
||||
/* JavaCCOptions: */
|
||||
package org.luaj.vm2.parser;
|
||||
|
||||
/** Token Manager Error. */
|
||||
public class TokenMgrError extends Error
|
||||
{
|
||||
|
||||
/**
|
||||
* The version identifier for this Serializable class.
|
||||
* Increment only if the <i>serialized</i> form of the
|
||||
* class changes.
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/*
|
||||
* Ordinals for various reasons why an Error of this type can be thrown.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Lexical error occurred.
|
||||
*/
|
||||
static final int LEXICAL_ERROR = 0;
|
||||
|
||||
/**
|
||||
* An attempt was made to create a second instance of a static token manager.
|
||||
*/
|
||||
static final int STATIC_LEXER_ERROR = 1;
|
||||
|
||||
/**
|
||||
* Tried to change to an invalid lexical state.
|
||||
*/
|
||||
static final int INVALID_LEXICAL_STATE = 2;
|
||||
|
||||
/**
|
||||
* Detected (and bailed out of) an infinite loop in the token manager.
|
||||
*/
|
||||
static final int LOOP_DETECTED = 3;
|
||||
|
||||
/**
|
||||
* Indicates the reason why the exception is thrown. It will have
|
||||
* one of the above 4 values.
|
||||
*/
|
||||
int errorCode;
|
||||
|
||||
/**
|
||||
* Replaces unprintable characters by their escaped (or unicode escaped)
|
||||
* equivalents in the given string
|
||||
*/
|
||||
protected static final String addEscapes(String str) {
|
||||
StringBuffer retval = new StringBuffer();
|
||||
char ch;
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
switch (str.charAt(i))
|
||||
{
|
||||
case 0 :
|
||||
continue;
|
||||
case '\b':
|
||||
retval.append("\\b");
|
||||
continue;
|
||||
case '\t':
|
||||
retval.append("\\t");
|
||||
continue;
|
||||
case '\n':
|
||||
retval.append("\\n");
|
||||
continue;
|
||||
case '\f':
|
||||
retval.append("\\f");
|
||||
continue;
|
||||
case '\r':
|
||||
retval.append("\\r");
|
||||
continue;
|
||||
case '\"':
|
||||
retval.append("\\\"");
|
||||
continue;
|
||||
case '\'':
|
||||
retval.append("\\\'");
|
||||
continue;
|
||||
case '\\':
|
||||
retval.append("\\\\");
|
||||
continue;
|
||||
default:
|
||||
if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
|
||||
String s = "0000" + Integer.toString(ch, 16);
|
||||
retval.append("\\u" + s.substring(s.length() - 4, s.length()));
|
||||
} else {
|
||||
retval.append(ch);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return retval.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a detailed message for the Error when it is thrown by the
|
||||
* token manager to indicate a lexical error.
|
||||
* Parameters :
|
||||
* EOFSeen : indicates if EOF caused the lexical error
|
||||
* curLexState : lexical state in which this error occurred
|
||||
* errorLine : line number when the error occurred
|
||||
* errorColumn : column number when the error occurred
|
||||
* errorAfter : prefix that was seen before this error occurred
|
||||
* curchar : the offending character
|
||||
* Note: You can customize the lexical error message by modifying this method.
|
||||
*/
|
||||
protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
|
||||
return("Lexical error at line " +
|
||||
errorLine + ", column " +
|
||||
errorColumn + ". Encountered: " +
|
||||
(EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
|
||||
"after : \"" + addEscapes(errorAfter) + "\"");
|
||||
}
|
||||
|
||||
/**
|
||||
* You can also modify the body of this method to customize your error messages.
|
||||
* For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
|
||||
* of end-users concern, so you can return something like :
|
||||
*
|
||||
* "Internal Error : Please file a bug report .... "
|
||||
*
|
||||
* from this method for such cases in the release version of your parser.
|
||||
*/
|
||||
public String getMessage() {
|
||||
return super.getMessage();
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructors of various flavors follow.
|
||||
*/
|
||||
|
||||
/** No arg constructor. */
|
||||
public TokenMgrError() {
|
||||
}
|
||||
|
||||
/** Constructor with message and reason. */
|
||||
public TokenMgrError(String message, int reason) {
|
||||
super(message);
|
||||
errorCode = reason;
|
||||
}
|
||||
|
||||
/** Full Constructor. */
|
||||
public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
|
||||
this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
|
||||
}
|
||||
}
|
||||
/* JavaCC - OriginalChecksum=bd3720425dc7b44a5223b12676db358c (do not edit this line) */
|
||||
Reference in New Issue
Block a user