/******************************************************************************* * Copyright (c) 2010-2012 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. ******************************************************************************/ /** * Javacc grammar used to produce a parse tree. Based on lua 5.2 syntax. * */ options { STATIC = false; JDK_VERSION = "1.3"; ERROR_REPORTING = true; UNICODE_INPUT = true; DEBUG_LOOKAHEAD = false; DEBUG_PARSER = false; DEBUG_TOKEN_MANAGER = false; OUTPUT_DIRECTORY = "src/jse/org/luaj/vm2/parser"; } PARSER_BEGIN(LuaParser) package org.luaj.vm2.parser; import org.luaj.vm2.*; import org.luaj.vm2.ast.*; import java.util.*; public class LuaParser { static { LuaValue.valueOf(true); } public static void main(String args[]) throws ParseException { LuaParser parser = new LuaParser(System.in); parser.Chunk(); } private static Exp.VarExp assertvarexp(Exp.PrimaryExp pe) throws ParseException { if (!pe.isvarexp()) throw new ParseException("expected variable"); return (Exp.VarExp) pe; } private static Exp.FuncCall assertfunccall(Exp.PrimaryExp pe) throws ParseException { if (!pe.isfunccall()) throw new ParseException("expected function call"); return (Exp.FuncCall) pe; } public SimpleCharStream getCharStream() { return jj_input_stream; } private long LineInfo() { return ((long) jj_input_stream.getBeginLine() << 32) | jj_input_stream.getBeginColumn(); } private void L(SyntaxElement e, long startinfo) { e.beginLine = (int) (startinfo >> 32); e.beginColumn = (short) startinfo; e.endLine = token.endLine; e.endColumn = (short) token.endColumn; } private void L(SyntaxElement e, Token starttoken) { e.beginLine = starttoken.beginLine; e.beginColumn = (short) starttoken.beginColumn; e.endLine = token.endLine; e.endColumn = (short) token.endColumn; } } PARSER_END(LuaParser) /* WHITE SPACE */ SKIP : { " " | "\t" | "\n" | "\r" | "\f" } /* COMMENTS and LONG STRINGS */ MORE : { "--[[": IN_LC0 | "--[=[": IN_LC1 | "--[==[": IN_LC2 | "--[===[": IN_LC3 | < "--[====" ("=")* "[" > : IN_LCN | "[[" : IN_LS0 | "[=[" : IN_LS1 | "[==[" : IN_LS2 | "[===[" : IN_LS3 | < "[====" ("=")* "[" > : IN_LSN | "--" : IN_COMMENT } SPECIAL_TOKEN : { : DEFAULT } SPECIAL_TOKEN : { : DEFAULT } SPECIAL_TOKEN : { : DEFAULT } SPECIAL_TOKEN : { : DEFAULT } SPECIAL_TOKEN : { : DEFAULT } SPECIAL_TOKEN : { : DEFAULT } TOKEN : { : DEFAULT } TOKEN : { : DEFAULT } TOKEN : { : DEFAULT } TOKEN : { : DEFAULT } TOKEN : { : DEFAULT } MORE : { < ~[] > } /* RESERVED WORDS AND LITERALS */ TOKEN : { | | | | | | | | | | | | | | | | | | | | | } /* LITERALS */ TOKEN : { < NAME: ["a"-"z", "A"-"Z", "_"] (["a"-"z", "A"-"Z", "_", "0"-"9"])* > | < NUMBER: | > | < #FLOAT: ()? > | < #FNUM: ()+ "." ()* | "." ()+ | ()+ > | < #DIGIT: ["0"-"9"] > | < #EXP: ["e","E"] (["+","-"])? ()+ > | < #HEX: "0" ["x","X"] ()? > | < #HEXNUM: ()+ "." ()* | "." ()+ | ()+ > | < #HEXDIGIT: ["0"-"9","a"-"f","A"-"F"] > | < #HEXEXP: ["e","E","p","P"] (["+","-"])? ()+ > | < STRING: "\"" ( | ~["\\","\""])* "\"" > | < CHARSTRING: "'" ( | ~["\\","'"])* "'" > | < #QUOTED: | | > | < #DECIMAL: "\\" ["0"-"9"] (["0"-"9"])? (["0"-"9"])? > | < DBCOLON: "::" > | < #UNICODE: "\\" "u" > | < #CHAR: "\\" (~[]) > | < #LF: ("\n" | "\r" | "\r\n") > } /** Root production. */ Chunk Chunk(): { Block b; Chunk c; long i = LineInfo(); } { ( "#" { token_source.SwitchTo(IN_COMMENT); } )? b=Block() { c=new Chunk(b); L(c,i); return c; } } Block Block(): { Block b = new Block(); Stat s; long i = LineInfo(); } { (s=Stat() {b.add(s);} )* (s=ReturnStat() {b.add(s);} )? { L(b,i); return b; } } Stat Stat(): { Block b,b2; Exp e,e2,e3=null; Stat s; FuncName fn; FuncBody fb; Token n; List nl; List el=null; long i = LineInfo(); } { ";" { return null; } | s=Label() { L(s,i); return s; } | { s=Stat.breakstat(); L(s,i); return s; } | n= { s=Stat.gotostat(n.image); L(s,i); return s; } | b=Block() { s=Stat.block(b); L(s,i); return s; } | e=Exp() b=Block() { s=Stat.whiledo(e,b); L(s,i); return s; } | b=Block() e=Exp() { s=Stat.repeatuntil(b,e); L(s,i); return s; } | s=IfThenElse() { L(s,i); return s; } | LOOKAHEAD(3) n= "=" e=Exp() "," e2=Exp() ( "," e3=Exp() )? b=Block() { s=Stat.fornumeric(n.image,e,e2,e3,b); L(s,i); return s; } | nl=NameList() el=ExpList() b=Block() { s=Stat.forgeneric(nl,el,b); L(s,i); return s; } | fn=FuncName() fb=FuncBody() { s=Stat.functiondef(fn,fb); L(s,i); return s; } | LOOKAHEAD(2) n= fb=FuncBody() { s=Stat.localfunctiondef(n.image,fb); L(s,i); return s; } | nl=NameList() ( "=" el=ExpList() )? { s=Stat.localassignment(nl,el); L(s,i); return s; } | s=ExprStat() { L(s,i); return s; } } Stat IfThenElse(): { Block b,b2,b3=null; Exp e,e2; List el=null; List bl=null; } { e=Exp() b=Block() ( e2=Exp() b2=Block() { if (el==null) el=new ArrayList(); if (bl==null) bl=new ArrayList(); el.add(e2); bl.add(b2); } )* ( b3=Block())? { return Stat.ifthenelse(e,b,el,bl,b3); } } Stat ReturnStat(): { List el=null; Stat s; long i = LineInfo(); } { ( el=ExpList() )? ( ";" )? { s=Stat.returnstat(el); L(s,i); return s; } } Stat Label(): { Token n; } { n= { return Stat.labelstat(n.image); } } Stat ExprStat(): { Exp.PrimaryExp p; Stat s=null; long i = LineInfo(); } { p=PrimaryExp() ( s=Assign(assertvarexp(p)) )? { if (s==null) { s=Stat.functioncall(assertfunccall(p)); } L(s,i); return s; } } Stat Assign(Exp.VarExp v0): { List vl = new ArrayList(); vl.add(v0); Exp.VarExp ve; List el; Stat s; long i = LineInfo(); } { ( "," ve=VarExp() { vl.add(ve); } )* "=" el=ExpList() { s=Stat.assignment(vl,el); L(s,i); return s; } } Exp.VarExp VarExp(): { Exp.PrimaryExp p; } { p=PrimaryExp() { return assertvarexp(p); } } FuncName FuncName(): { Token n; FuncName f; } { n= {f=new FuncName(n.image);} ( "." n= {f.adddot(n.image);} )* ( ":" n= {f.method=n.image;} )? {L(f,n); return f;} } Exp.PrimaryExp PrefixExp(): { Token n; Exp e; Exp.PrimaryExp p; long i = LineInfo(); } { n= { p=Exp.nameprefix(n.image); L(p,i); return p; } | "(" e=Exp() ")" { p=Exp.parensprefix(e); L(p,i); return p; } } Exp.PrimaryExp PrimaryExp(): { Exp.PrimaryExp p; long i = LineInfo(); } { p=PrefixExp() ( LOOKAHEAD(2) p=PostfixOp(p) )* { L(p,i); return p; } } Exp.PrimaryExp PostfixOp(Exp.PrimaryExp lhs): { Token n; Exp e; FuncArgs a; Exp.PrimaryExp p; long i = LineInfo(); } { "." n= { p=Exp.fieldop(lhs, n.image); L(p,i); return p; } | "[" e=Exp() "]" { p=Exp.indexop(lhs, e); L(p,i); return p; } | ":" n= a=FuncArgs() { p=Exp.methodop(lhs, n.image,a); L(p,i); return p; } | a=FuncArgs() { p=Exp.functionop(lhs, a); L(p,i); return p; } } FuncArgs FuncArgs(): { List el=null; TableConstructor tc; LuaString s; FuncArgs a; long i = LineInfo(); } { "(" ( el=ExpList() )? ")" { a=FuncArgs.explist(el); L(a,i); return a; } | tc=TableConstructor() { a=FuncArgs.tableconstructor(tc); L(a,i); return a; } | s=Str() { a=FuncArgs.string(s); L(a,i); return a; } } List NameList(): { List l = new ArrayList(); Token name; } { name= {l.add(new Name(name.image));} ( LOOKAHEAD(2) "," name= {l.add(new Name(name.image));} )* {return l;} } List ExpList(): { List l = new ArrayList(); Exp e; } { e=Exp() {l.add(e);} ( "," e=Exp() {l.add(e);} )* {return l;} } Exp SimpleExp(): { Token n; LuaString s; Exp e; TableConstructor c; FuncBody b; long i = LineInfo(); } { { e=Exp.constant(LuaValue.NIL); L(e,i); return e; } | { e=Exp.constant(LuaValue.TRUE); L(e,i); return e; } | { e=Exp.constant(LuaValue.FALSE); L(e,i); return e; } | n= { e=Exp.numberconstant(n.image); L(e,i); return e; } | s=Str() { e=Exp.constant(s); L(e,i); return e; } | "..." { e=Exp.varargs(); L(e,i); return e; } | c=TableConstructor() { e=Exp.tableconstructor(c); L(e,i); return e; } | b=FunctionCall() { e=Exp.anonymousfunction(b); L(e,i); return e; } | e=PrimaryExp() { return e; } } LuaString Str(): {} { { return Str.quoteString(token.image); } | { return Str.charString(token.image); } | { return Str.longString(token.image); } | { return Str.longString(token.image); } | { return Str.longString(token.image); } | { return Str.longString(token.image); } | { return Str.longString(token.image); } } Exp Exp(): { Exp e,s; int op; long i = LineInfo(); } { ( e=SimpleExp() | op=Unop() s=Exp() {e=Exp.unaryexp(op,s);}) (LOOKAHEAD(2) op=Binop() s=Exp() {e=Exp.binaryexp(e,op,s);} )* { L(e,i); return e; } } FuncBody FunctionCall(): { FuncBody b; long i = LineInfo(); } { b=FuncBody() { L(b,i); return b; } } FuncBody FuncBody(): { ParList pl=null; Block b; FuncBody f; long i = LineInfo(); } { "(" ( pl=ParList() )? ")" b=Block() { f=new FuncBody(pl,b); L(f,i); return f; } } ParList ParList(): { List l=null; boolean v=false; ParList p; long i = LineInfo(); } { l=NameList() ( "," "..." { v=true; } )? { p=new ParList(l,v); L(p,i); return p; } | "..." { p=new ParList(null,true); L(p,i); return p; } } TableConstructor TableConstructor(): { TableConstructor c = new TableConstructor(); List l = null; long i = LineInfo(); } { "{" ( l=FieldList() {c.fields=l;} )? "}" { L(c,i); return c; } } List FieldList(): { List l = new ArrayList(); TableField f; } { f=Field() {l.add(f);} (LOOKAHEAD(2) FieldSep() f=Field() {l.add(f);})* (FieldSep())? { return l; } } TableField Field(): { Token name; Exp exp,rhs; TableField f; long i = LineInfo(); } { "[" exp=Exp() "]" "=" rhs=Exp() { f=TableField.keyedField(exp,rhs); L(f,i); return f; } | LOOKAHEAD(2) name= "=" rhs=Exp() { f=TableField.namedField(name.image,rhs); L(f,i); return f; } | rhs=Exp() { f=TableField.listField(rhs); L(f,i); return f; } } void FieldSep(): {} { "," | ";" } int Binop(): {} { "+" { return Lua.OP_ADD; } | "-" { return Lua.OP_SUB; } | "*" { return Lua.OP_MUL; } | "/" { return Lua.OP_DIV; } | "^" { return Lua.OP_POW; } | "%" { return Lua.OP_MOD; } | ".." { return Lua.OP_CONCAT; } | "<" { return Lua.OP_LT; } | "<=" { return Lua.OP_LE; } | ">" { return Lua.OP_GT; } | ">=" { return Lua.OP_GE; } | "==" { return Lua.OP_EQ; } | "~=" { return Lua.OP_NEQ; } | { return Lua.OP_AND; } | { return Lua.OP_OR; } } int Unop(): {} { "-" { return Lua.OP_UNM; } | { return Lua.OP_NOT; } | "#" { return Lua.OP_LEN; } }