/* QBJ compiler parser specification */ /* Copyright 1999-2000 Toshihiro Horie */ import java_cup.runtime.*; init with {: :} scan with {: return getScanner().next_token(); :} /* terminals (tokens returned by the scanner) */ terminal TokenValue tNEWLINE; terminal TokenValue tPOUND; terminal TokenValue tSEMI; terminal TokenValue tCOMMA; terminal TokenValue tPERIOD; terminal TokenValue tPLUS; terminal TokenValue tMINUS; terminal TokenValue tTIMES; terminal TokenValue tDIVIDE; terminal TokenValue tLPAREN; terminal TokenValue tRPAREN; terminal TokenValue tASSIGN; terminal TokenValue tNE; terminal TokenValue tGT; terminal TokenValue tLT; terminal TokenValue tLE; terminal TokenValue tGE; terminal TokenValue tCOLON; terminal TokenValue tABSOLUTE; terminal TokenValue tABS; terminal TokenValue tACCESS; terminal TokenValue tALIAS; terminal TokenValue tAND; terminal TokenValue tANY; terminal TokenValue tAPPEND; terminal TokenValue tAS; terminal TokenValue tASC; terminal TokenValue tATN; terminal TokenValue tBASE; terminal TokenValue tBEEP; terminal TokenValue tBINARY; terminal TokenValue tBLOAD; terminal TokenValue tBSAVE; terminal TokenValue tBYVAL; terminal TokenValue tCALLS; terminal TokenValue tCDBL; terminal TokenValue tCDECL; terminal TokenValue tCHAIN; terminal TokenValue tCHDIR; terminal TokenValue tCHR_; terminal TokenValue tCINT; terminal TokenValue tCIRCLE; terminal TokenValue tCLEAR; terminal TokenValue tCLNG; terminal TokenValue tCLS; terminal TokenValue tCOLOR; terminal TokenValue tCOM; terminal TokenValue tCOMMAND_; terminal TokenValue tCOMMON; terminal TokenValue tCONST; terminal TokenValue tCOS; terminal TokenValue tCSNG; terminal TokenValue tCSRLIN; terminal TokenValue tCVD; terminal TokenValue tCVDMBF; terminal TokenValue tCVI; terminal TokenValue tCVL; terminal TokenValue tCVS; terminal TokenValue tDATE_; terminal TokenValue tDRAW; terminal TokenValue tENVIRON; terminal TokenValue tENVIRON_; terminal TokenValue tEOF; terminal TokenValue tEQV; terminal TokenValue tERASE; terminal TokenValue tERDEV; terminal TokenValue tERDEV_; terminal TokenValue tERL; terminal TokenValue tERR; terminal TokenValue tERROR; terminal TokenValue tEXIT; terminal TokenValue tEXP; terminal TokenValue tFIX; terminal TokenValue tFUNCTION; terminal TokenValue tGET; terminal TokenValue tHEX_; terminal TokenValue tIMP; terminal TokenValue tINKEY_; terminal TokenValue tINP; terminal TokenValue tINPUT; terminal TokenValue tINPUT_; terminal TokenValue tINSTR; terminal TokenValue tINT; terminal TokenValue tINTEGER; terminal TokenValue tINTERRUPT; terminal TokenValue tIOCTL; terminal TokenValue tIOCTL_; terminal TokenValue tIS; terminal TokenValue tKEY; terminal TokenValue tKILL; terminal TokenValue tLBOUND; terminal TokenValue tLCASE_; terminal TokenValue tLEFT_; terminal TokenValue tLEN; terminal TokenValue tLET; terminal TokenValue tLINE; terminal TokenValue tLIST; terminal TokenValue tLOC; terminal TokenValue tLOCAL; terminal TokenValue tLOCATE; terminal TokenValue tLOCK; terminal TokenValue tLOF; terminal TokenValue tLOG; terminal TokenValue tLONG; terminal TokenValue tLPOS; terminal TokenValue tLPRINT; terminal TokenValue tLSET; terminal TokenValue tLTRIM_; terminal TokenValue tMID_; terminal TokenValue tMOD; terminal TokenValue tNAME; terminal TokenValue tNOT; terminal TokenValue tOCT_; terminal TokenValue tOFF; terminal TokenValue tOPEN; terminal TokenValue tOR; terminal TokenValue tOUT; terminal TokenValue tOUTPUT; terminal TokenValue tPAINT; terminal TokenValue tPALETTE; terminal TokenValue tPCOPY; terminal TokenValue tPEEK; terminal TokenValue tPEN; terminal TokenValue tPLAY; terminal TokenValue tPMAP; terminal TokenValue tPOINT; terminal TokenValue tPOKE; terminal TokenValue tPOS; terminal TokenValue tPRESET; terminal TokenValue tPRINT; terminal TokenValue tPSET; terminal TokenValue tPUT; terminal TokenValue tRANDOM; terminal TokenValue tRANDOMIZE; terminal TokenValue tREAD; terminal TokenValue tRESET; terminal TokenValue tRESTORE; terminal TokenValue tRIGHT_; terminal TokenValue tRMDIR; terminal TokenValue tRND; terminal TokenValue tRSET; terminal TokenValue tRTRIM_; terminal TokenValue tRUN; terminal TokenValue tSADD; terminal TokenValue tSCREEN; terminal TokenValue tSEEK; terminal TokenValue tSEG; terminal TokenValue tSETMEM; terminal TokenValue tSGN; terminal TokenValue tSIGNAL; terminal TokenValue tSIN; terminal TokenValue tSLEEP; terminal TokenValue tSOUND; terminal TokenValue tSPACE_; terminal TokenValue tSPC; terminal TokenValue tSQR; terminal TokenValue tSSEG; terminal TokenValue tSTICK; terminal TokenValue tSTRIG; terminal TokenValue tSTRING; terminal TokenValue tSTRING_; terminal TokenValue tSUB; terminal TokenValue tSWAP; terminal TokenValue tTAB; terminal TokenValue tTAN; terminal TokenValue tTIME_; terminal TokenValue tTIMER; terminal TokenValue tTROFF; terminal TokenValue tTRON; terminal TokenValue tUBOUND; terminal TokenValue tUCASE_; terminal TokenValue tUEVENT; terminal TokenValue tUNLOCK; terminal TokenValue tUSING; terminal TokenValue tVAL; terminal TokenValue tVARPTR; terminal TokenValue tVARPTR_; terminal TokenValue tVARSEG; terminal TokenValue tVIEW; terminal TokenValue tWAIT; terminal TokenValue tWIDTH; terminal TokenValue tWINDOW; terminal TokenValue tWRITE; terminal TokenValue tXOR; terminal TokenValue tCALL; terminal TokenValue tCASE; terminal TokenValue tDO; terminal TokenValue tELSE; terminal TokenValue tEND; terminal TokenValue tFOR; terminal TokenValue tGOSUB; terminal TokenValue tGOTO; terminal TokenValue tIF; terminal TokenValue tLOOP; terminal TokenValue tNEXT; terminal TokenValue tON; terminal TokenValue tRESUME; terminal TokenValue tRETURN; terminal TokenValue tSELECT; terminal TokenValue tSHELL; terminal TokenValue tSTEP; terminal TokenValue tSTOP; terminal TokenValue tSYSTEM; terminal TokenValue tTHEN; terminal TokenValue tTO; terminal TokenValue tUNTIL; terminal TokenValue tWEND; terminal TokenValue tWHILE; terminal TokenValue tDATA; terminal TokenValue tDECLARE; terminal TokenValue tDEF; terminal TokenValue tDEFDBL; terminal TokenValue tDEFINT; terminal TokenValue tDEFSNG; terminal TokenValue tDEFLNG; terminal TokenValue tDEFSTR; terminal TokenValue tDIM; terminal TokenValue tDOUBLE; terminal TokenValue tFN; terminal TokenValue tOPTION; terminal TokenValue tREDIM; terminal TokenValue tSINGLE; terminal TokenValue tSHARED; terminal TokenValue tSTATIC; terminal TokenValue tTYPE; terminal TokenValue tNUM; terminal TokenValue tSTRINGTEXT; terminal TokenValue tVAR; terminal TokenValue tENDSELECT; terminal TokenValue tSINGLEVAR; terminal TokenValue tDOUBLEVAR; terminal TokenValue tINTEGERVAR; terminal TokenValue tSTRINGVAR; terminal TokenValue tLONGVAR; terminal TokenValue tIDIV; terminal TokenValue tCARET; terminal TokenValue tMETASTATIC; terminal TokenValue tMETADYNAMIC; terminal TokenValue tMETAINCLUDE; terminal TokenValue tINCLUDEFILE; terminal TokenValue tLABEL; // special virtual terminals with different meanings terminal TokenValue UMINUS; terminal TokenValue EQ; // use tab stops = 4 non terminal QBJDecl program; non terminal SubDecl sub; non terminal FuncDecl func; non terminal VarList varlist; non terminal FrmlArgList farglist; non terminal DeclList typelist; non terminal VarDecl stvardecl,fvardecl,farrvardecl; non terminal TypeDecl typedecl; non terminal Stmt stmt; non terminal CaseStmt casestmt; non terminal IfStmt ifstmt; non terminal StmtList stmtlist; non terminal Stmt assignstmt; non terminal StmtList assignstmtlist; non terminal DeclList subfunclist; non terminal ExpList explist; non terminal StmtList caselist; non terminal Stmt inputstmt; non terminal Stmt subcallstmt; non terminal Stmt declaresubstmt; non terminal Stmt declarefuncstmt; non terminal Exp exp, wexp, boolexp, convexp; non terminal StringExp stringexp; non terminal Var var, svar; non terminal AsExp asexp; non terminal DimStmt dimstmt; non terminal RedimStmt redimstmt; non terminal ForStmt forstmt; non terminal Var smpvar; non terminal Var intvar; non terminal Var lngvar; non terminal Var sngvar; non terminal Var dblvar; non terminal Var strvar; // lowest precedence ***** // boolean operators precedence left tIMP; precedence left tEQV; precedence left tXOR; precedence left tOR; precedence left tAND; precedence left tNOT; // relational operators precedence left EQ, tGT, tLT,tNE, tLE, tGE; // arithmetic operators precedence left tPLUS, tMINUS; precedence left tMOD; precedence left tIDIV; precedence left tTIMES, tDIVIDE; precedence left UMINUS; precedence left tCARET; // others precedence left tLPAREN, tRPAREN; // highest precedence ***** start with program; program::= stmtlist:mainsl subfunclist:functions stmtlist:restofsl {: /* should do mainsl.append(restofsl); */ RESULT=new QBJDecl(mainsl.lineBegin, mainsl.charBegin, mainsl, functions); :} | stmtlist:mainsl subfunclist:functions {: RESULT=new QBJDecl(mainsl.lineBegin, mainsl.charBegin, mainsl, functions); :} | stmtlist:mainsl {: RESULT=new QBJDecl(mainsl.lineBegin, mainsl.charBegin, mainsl, null); :} ; subfunclist::= subfunclist:dlist stmtlist:crap sub:aSub {: /* aSub.sl.prepend(crap); */ RESULT=dlist.append(aSub); :} | subfunclist:dlist stmtlist:crap func:aFunc {: /* aFunc.sl.prepend(crap); */ RESULT=dlist.append(aFunc); :} | subfunclist:dlist sub:aSub {: RESULT=dlist.append(aSub); :} | subfunclist:dlist func:aFunc {: RESULT=dlist.append(aFunc); :} | sub:aSub {: RESULT=new DeclList(aSub); :} | func:aFunc {: RESULT=new DeclList(aFunc); :} ; stmtlist::= stmtlist:sl stmt:st {: RESULT=sl.append(st); :} | stmt:st {: RESULT=new StmtList(st); :} ; explist::= explist:el tCOMMA wexp:e {: RESULT=el.append(e); :} | wexp:e {: RESULT=new ExpList(e); :} ; caselist::= caselist:cl casestmt:c {: RESULT=cl.append(c); :} | casestmt:c {: RESULT=new StmtList(c); :} ; varlist::= varlist:vl tCOMMA var:v {: RESULT=vl.append(v); :} | var:v {: RESULT=new VarList(v); :} ; var::= svar:v {: RESULT=v; :} | svar:v tLPAREN explist:indexlist tRPAREN {: /* this may actually be a function call! funccallexp */ RESULT=new SubscriptVar(v.lineBegin, v.charBegin, v, indexlist); :} | svar:v tLPAREN explist:indexlist tRPAREN tPERIOD svar:r {: /* FIXME - selection new TypeSelectVar */ RESULT=new SubscriptVar(v.lineBegin, v.charBegin, v, indexlist); :} ; ifstmt::= tIF:v exp:testexp tNEWLINE {: System.err.println("You must put the THEN on the same line as the IF "+(v.lineBegin+1)); System.exit(1); :} | tIF:v exp:testexp tTHEN tNEWLINE stmtlist:thenpart tEND tIF tNEWLINE {: RESULT=new IfStmt(v.lineBegin, v.charBegin, testexp, thenpart, null); :} | tIF:v exp:testexp tTHEN tNEWLINE stmtlist:thenpart tELSE tNEWLINE stmtlist:elsepart tEND tIF tNEWLINE {: RESULT=new IfStmt(v.lineBegin, v.charBegin, testexp, thenpart, elsepart); :} | tIF:v exp:testexp tTHEN tNEWLINE stmtlist:thenpart tELSE tIF {: System.err.println("Please use 'ELSEIF' instead of ELSE IF on line "+(v.lineBegin+1)); System.exit(1); :} ; strvar::= tSTRINGVAR:v {: RESULT=new SimpleVar(v.lineBegin, v.charBegin, v.text, SimpleVar.cSTRING); :} ; smpvar::= tVAR:v {: RESULT=new SimpleVar(v.lineBegin, v.charBegin, v.text); :} ; sngvar::= tSINGLEVAR:v {: RESULT=new SimpleVar(v.lineBegin, v.charBegin, v.text, SimpleVar.cSINGLE); :} ; dblvar::= tDOUBLEVAR:v {: RESULT=new SimpleVar(v.lineBegin, v.charBegin, v.text, SimpleVar.cDOUBLE); :} ; intvar::= tINTEGERVAR:v {: RESULT=new SimpleVar(v.lineBegin, v.charBegin, v.text, SimpleVar.cINTEGER); :} ; lngvar::= tLONGVAR:v {: RESULT=new SimpleVar(v.lineBegin, v.charBegin, v.text, SimpleVar.cLONG); :} ; svar::= smpvar:v {: RESULT=v; :} | sngvar:v {: RESULT=v; :} | dblvar:v {: RESULT=v; :} | intvar:v {: RESULT=v; :} | lngvar:v {: RESULT=v; :} | strvar:v {: RESULT=v; :} ; assignstmtlist::= assignstmtlist:aslist tCOMMA assignstmt:st {: RESULT=aslist.append(st); :} | assignstmt:st {: RESULT=new StmtList(st); :} ; assignstmt::= var:v tASSIGN:eq exp:value {: RESULT=new AssignStmt(eq.lineBegin, eq.charBegin, v, value); :} ; sub::= tSUB:s tVAR:id tNEWLINE stmtlist:body tEND tSUB tNEWLINE {: /* note: check for SUB nesting error in semantcheck */ RESULT=new SubDecl(s.lineBegin, s.charBegin, id.text, body); :} | tSUB:s tVAR:id tLPAREN farglist:flist tRPAREN tNEWLINE stmtlist:body tEND tSUB tNEWLINE {: RESULT=new SubDecl(s.lineBegin, s.charBegin, id.text, flist, body); :} ; func::= tFUNCTION:s tVAR:idtok tNEWLINE stmtlist:body tEND tFUNCTION tNEWLINE {: RESULT=new FuncDecl(s.lineBegin, s.charBegin, idtok.text,null,body); :} | tFUNCTION:s tVAR:idtok tLPAREN farglist:flist tRPAREN tNEWLINE stmtlist:body tEND tFUNCTION tNEWLINE {: RESULT=new FuncDecl(s.lineBegin, s.charBegin, idtok.text,flist,body); :} | tFUNCTION:s strvar:idvar tLPAREN farglist:flist tRPAREN tNEWLINE stmtlist:body tEND tSUB tNEWLINE {: RESULT=new FuncDecl(s.lineBegin, s.charBegin, idvar, flist, body); :} | tFUNCTION:s intvar:idvar tLPAREN farglist:flist tRPAREN tNEWLINE stmtlist:body tEND tSUB tNEWLINE {: RESULT=new FuncDecl(s.lineBegin, s.charBegin, idvar, flist, body); :} | tFUNCTION:s lngvar:idvar tLPAREN farglist:flist tRPAREN tNEWLINE stmtlist:body tEND tSUB tNEWLINE {: RESULT=new FuncDecl(s.lineBegin, s.charBegin, idvar, flist, body); :} | tFUNCTION:s sngvar:idvar tLPAREN farglist:flist tRPAREN tNEWLINE stmtlist:body tEND tSUB tNEWLINE {: RESULT=new FuncDecl(s.lineBegin, s.charBegin, idvar, flist, body); :} | tFUNCTION:s dblvar:idvar tLPAREN farglist:flist tRPAREN tNEWLINE stmtlist:body tEND tSUB tNEWLINE {: RESULT=new FuncDecl(s.lineBegin, s.charBegin, idvar, flist, body); :} ; subcallstmt::= tCALL:c var:v tNEWLINE {: RESULT=new SubCallStmt(c.lineBegin, c.charBegin, v, null); :} | var:v tNEWLINE {: RESULT=new SubCallStmt(v.lineBegin, v.charBegin, v, null); :} | tCALL:c var:v tLPAREN explist:el tRPAREN tNEWLINE {: RESULT=new SubCallStmt(c.lineBegin, c.charBegin, v, el); :} ; convexp::= tCINT:n tLPAREN exp:e tRPAREN {: RESULT=new CintExp(n.lineBegin, n.charBegin, e); :} | tCLNG:n tLPAREN exp:e tRPAREN {: RESULT=new ClngExp(n.lineBegin, n.charBegin, e); :} | tCDBL:n tLPAREN exp:e tRPAREN {: RESULT=new CdblExp(n.lineBegin, n.charBegin, e); :} | tCSNG:n tLPAREN exp:e tRPAREN {: RESULT=new CsngExp(n.lineBegin, n.charBegin, e); :} | tFIX:n tLPAREN exp:e tRPAREN {: RESULT=new FixExp(n.lineBegin, n.charBegin, e); :} | tINT:n tLPAREN exp:e tRPAREN {: RESULT=new IntFloorExp(n.lineBegin, n.charBegin, e); :} ; boolexp::= tNOT:op exp:e {: RESULT=new UopExp(op.lineBegin, op.charBegin, UopExp.NOT, e); :} | exp:left tAND:op exp:right {: RESULT=new BopExp(op.lineBegin, op.charBegin, left, BopExp.AND, right); :} | exp:left tOR:op exp:right {: RESULT=new BopExp(op.lineBegin, op.charBegin, left, BopExp.OR, right); :} | exp:left tXOR:op exp:right {: RESULT=new BopExp(op.lineBegin, op.charBegin, left, BopExp.XOR, right); :} | exp:left tEQV:op exp:right {: RESULT=new BopExp(op.lineBegin, op.charBegin, left, BopExp.EQV, right); :} | exp:left tIMP:op exp:right {: RESULT=new BopExp(op.lineBegin, op.charBegin, left, BopExp.IMP, right); :} ; exp::= tNUM:n {: RESULT=new NumberExp(n.lineBegin, n.charBegin, n.text); :} | convexp:e {: RESULT=e; :} | var:v {: /* this may be a FuncCallExp with no arguments */ RESULT=new DerefExp(v.lineBegin, v.charBegin, v); :} | tPEEK:p tLPAREN exp:e tRPAREN {: RESULT=new PeekExp(p.lineBegin, p.charBegin, e); :} | tPOINT:op tLPAREN exp:x tCOMMA exp:y tRPAREN {: RESULT=new PointExp(op.lineBegin, op.charBegin, x,y); :} | tPOINT:op tLPAREN exp:mode tRPAREN {: RESULT=new PointExp(op.lineBegin, op.charBegin, mode); :} | tCSRLIN:op {: RESULT=new CsrlinExp(op.lineBegin, op.charBegin); :} | tVAL:op tLPAREN exp:e tRPAREN {: RESULT=new ValExp(op.lineBegin, op.charBegin,e); :} | tSCREEN:op tLPAREN exp:row tCOMMA exp:col tCOMMA exp:colorflag tRPAREN {: RESULT=new ScreenExp(op.lineBegin, op.charBegin,row,col,colorflag); :} | tSCREEN:op tLPAREN exp:row tCOMMA exp:col tRPAREN {: RESULT=new ScreenExp(op.lineBegin, op.charBegin,row,col,null); :} | tPOS:op tLPAREN exp:num tRPAREN {: RESULT=new PosExp(op.lineBegin, op.charBegin, num); :} | tINKEY_:op {: RESULT=new InkeyExp(op.lineBegin, op.charBegin); :} | tLEN:op tLPAREN exp:e tRPAREN {: RESULT=new LenExp(op.lineBegin, op.charBegin, e); :} | tMID_:op tLPAREN exp:str tCOMMA exp:start tRPAREN {: RESULT=new MidMoneyExp(op.lineBegin, op.charBegin, str, start, null); :} | tMID_:op tLPAREN exp:str tCOMMA exp:start tCOMMA exp:end tRPAREN {: RESULT=new MidMoneyExp(op.lineBegin, op.charBegin, str, start, end); :} | tHEX_:op tLPAREN exp:num tRPAREN {: RESULT=new HexMoneyExp(op.lineBegin, op.charBegin, num); :} | tOCT_:op tLPAREN exp:num tRPAREN {: RESULT=new OctMoneyExp(op.lineBegin, op.charBegin, num); :} | exp:left tPLUS:op exp:right {: RESULT=new BopExp(op.lineBegin, op.charBegin, left,BopExp.PLUS, right); :} | exp:left tMOD:op exp:right {: RESULT=new BopExp(op.lineBegin, op.charBegin, left,BopExp.MOD, right); :} | exp:left tMINUS:op exp:right {: RESULT=new BopExp(op.lineBegin, op.charBegin, left,BopExp.MINUS, right); :} | exp:left tTIMES:op exp:right {: RESULT=new BopExp(op.lineBegin, op.charBegin, left,BopExp.MUL, right); :} | exp:left tDIVIDE:op exp:right {: RESULT=new BopExp(op.lineBegin, op.charBegin, left,BopExp.DIV, right); :} | exp:left tIDIV:op exp:right {: RESULT=new BopExp(op.lineBegin, op.charBegin, left,BopExp.IDIV, right); :} | exp:left tCARET:op exp:right {: RESULT=new BopExp(op.lineBegin, op.charBegin, left,BopExp.POW, right); :} | tMINUS exp:e {: RESULT = new UopExp(e.lineBegin, e.charBegin, UopExp.MINUS,e); :} %prec UMINUS | exp:left tASSIGN:op exp:right {: RESULT=new BopExp(op.lineBegin, op.charBegin, left,BopExp.EQ, right); :} %prec EQ | exp:left tGE:op exp:right {: RESULT=new BopExp(op.lineBegin, op.charBegin, left,BopExp.GE, right); :} | exp:left tGT:op exp:right {: RESULT=new BopExp(op.lineBegin, op.charBegin, left,BopExp.GT, right); :} | exp:left tLE:op exp:right {: RESULT=new BopExp(op.lineBegin, op.charBegin, left,BopExp.LE, right); :} | exp:left tLT:op exp:right {: RESULT=new BopExp(op.lineBegin, op.charBegin, left, BopExp.LT, right); :} | exp:left tNE:op exp:right {: RESULT=new BopExp(op.lineBegin, op.charBegin, left, BopExp.NE, right); :} | tDATE_:op {: RESULT=new DateMoneyExp(op.lineBegin, op.charBegin); :} | tTIME_:op {: RESULT=new TimeMoneyExp(op.lineBegin, op.charBegin); :} | tTIMER:op {: RESULT=new TimerExp(op.lineBegin, op.charBegin); :} | tSQR:op tLPAREN exp:e tRPAREN {: RESULT=new UopExp(op.lineBegin, op.charBegin, UopExp.SQR, e); :} | tSIN:op tLPAREN exp:e tRPAREN {: RESULT=new UopExp(op.lineBegin, op.charBegin, UopExp.SIN, e); :} | tCOS:op tLPAREN exp:e tRPAREN {: RESULT=new UopExp(op.lineBegin, op.charBegin, UopExp.COS, e); :} | tTAN:op tLPAREN exp:e tRPAREN {: RESULT=new UopExp(op.lineBegin, op.charBegin, UopExp.TAN, e); :} | tATN:op tLPAREN exp:e tRPAREN {: RESULT=new UopExp(op.lineBegin, op.charBegin, UopExp.ATN, e); :} | tABS:op tLPAREN exp:e tRPAREN {: RESULT=new UopExp(op.lineBegin, op.charBegin, UopExp.ABS, e); :} | tSGN:op tLPAREN exp:e tRPAREN {: RESULT=new UopExp(op.lineBegin, op.charBegin, UopExp.SGN, e); :} | tRND:op tLPAREN exp:e tRPAREN {: RESULT=new RndExp(op.lineBegin, op.charBegin, e); :} | tRND:op {: RESULT=new RndExp(op.lineBegin, op.charBegin, null); :} | tASC:a tLPAREN exp:e tRPAREN {: RESULT=new AscExp(a.lineBegin, a.charBegin, e); :} | tINP:a tLPAREN exp:e tRPAREN {: RESULT=new InpExp(a.lineBegin, a.charBegin, e); :} | tVARSEG:a tLPAREN exp:e tRPAREN {: RESULT=new VarsegExp(a.lineBegin, a.charBegin, e); :} | tVARPTR:a tLPAREN exp:e tRPAREN {: RESULT=new VarptrExp(a.lineBegin, a.charBegin, e); :} | tSSEG:a tLPAREN exp:e tRPAREN {: RESULT=new SsegExp(a.lineBegin, a.charBegin, e); :} | boolexp:e {: RESULT=e; :} | stringexp:s {: RESULT=s; :} | tLPAREN exp:e tRPAREN {: RESULT=e; :} ; wexp::= exp:upper {: RESULT=new RangeExp(upper.lineBegin, upper.charBegin,null,upper); :} | exp:lower tTO exp:upper {: /* used for CASE and DIM and REDIM statements */ RESULT=new RangeExp(lower.lineBegin, lower.charBegin,lower,upper); :} | tIS:left tASSIGN:op exp:right {: /* below rules are only used for CASE IS ... statements */ RESULT=new IsExp(op.lineBegin, op.charBegin, BopExp.EQ, right); :} %prec EQ | tIS:left tGE:op exp:right {: RESULT=new IsExp(op.lineBegin, op.charBegin, BopExp.GE, right); :} | tIS:left tGT:op exp:right {: RESULT=new IsExp(op.lineBegin, op.charBegin, BopExp.GT, right); :} | tIS:left tLE:op exp:right {: RESULT=new IsExp(op.lineBegin, op.charBegin, BopExp.LE, right); :} | tIS:left tLT:op exp:right {: RESULT=new IsExp(op.lineBegin, op.charBegin, BopExp.LT, right); :} | tIS:left tNE:op exp:right {: RESULT=new IsExp(op.lineBegin, op.charBegin, BopExp.NE, right); :} ; stringexp::= tSTRINGTEXT:t {: RESULT=new StringExp(t.lineBegin, t.charBegin, t.text); :} | stringexp:str tPLUS tSTRINGTEXT:t {: RESULT=str.concat(t.text); :} ; asexp::= tAS:s tSINGLE {: RESULT=new AsExp(s.lineBegin, s.charBegin, SimpleVar.cSINGLE); :} | tAS:s tDOUBLE {: RESULT=new AsExp(s.lineBegin, s.charBegin, SimpleVar.cDOUBLE); :} | tAS:s tINTEGER {: RESULT=new AsExp(s.lineBegin, s.charBegin, SimpleVar.cINTEGER); :} | tAS:s tLONG {: RESULT=new AsExp(s.lineBegin, s.charBegin, SimpleVar.cLONG); :} | tAS:s tSTRING tTIMES exp:length {: RESULT=new AsExp(s.lineBegin, s.charBegin, SimpleVar.cSTRING,length); :} | tAS:s tSTRING {: System.err.println("need to change to ... AS STRING * constantInteger on line "+(s.lineBegin+1)); System.exit(1); :} | tAS:s tSTRING tTIMES {: System.err.println("need to change to ... AS STRING * constantInteger on line "+(s.lineBegin+1)); System.exit(1); :} | tAS:s tVAR:v {: /* for a user-defined type named v.text */ RESULT=new AsExp(s.lineBegin, s.charBegin, v.text); :} | tAS:s {: System.err.println("AS what? Try AS INTEGER or something! on line "+(s.lineBegin+1)); System.exit(1); :} ; stmt::= tDEFINT:s tVAR:letter tNEWLINE {: /* note: these 2 rules don't cover all the cases */ RESULT=new DefintStmt(s.lineBegin, s.charBegin, letter.text); :} | tDEFINT:s tVAR:lowerletter tMINUS tVAR:upperletter tNEWLINE {: RESULT=new DefintStmt(s.lineBegin, s.charBegin, lowerletter.text,upperletter.text); :} | tDEFSNG:s tVAR:lowerletter tMINUS tVAR:upperletter tNEWLINE {: RESULT=new DefsngStmt(s.lineBegin, s.charBegin, lowerletter.text,upperletter.text); :} | tDEFLNG:s tVAR:lowerletter tMINUS tVAR:upperletter tNEWLINE {: RESULT=new DeflngStmt(s.lineBegin, s.charBegin, lowerletter.text,upperletter.text); :} | tDEFDBL:s tVAR:lowerletter tMINUS tVAR:upperletter tNEWLINE {: RESULT=new DefdblStmt(s.lineBegin, s.charBegin, lowerletter.text,upperletter.text); :} | tDEFSTR:s tVAR:letter tNEWLINE {: RESULT=new DefstrStmt(s.lineBegin, s.charBegin, letter.text); :} | tDEFSTR:s tVAR:lowerletter tMINUS tVAR:upperletter tNEWLINE {: RESULT=new DefstrStmt(s.lineBegin, s.charBegin, lowerletter.text,upperletter.text); :} | tBEEP:s tNEWLINE {: RESULT=new BeepStmt(s.lineBegin, s.charBegin); :} | tCLS:s tNEWLINE {: RESULT=new ClsStmt(s.lineBegin, s.charBegin, null); :} | tCLS:s exp:mode {: RESULT=new ClsStmt(s.lineBegin, s.charBegin, mode); :} | tCOLOR:s tNUM:forecolor tNEWLINE {: RESULT=new ColorStmt(s.lineBegin, s.charBegin, new Integer(forecolor.text).intValue()); :} | tCOLOR:s tNUM:forecolor tCOMMA tNUM:backcolor tNEWLINE {: RESULT=new ColorStmt(s.lineBegin, s.charBegin, new Integer(forecolor.text).intValue(), new Integer(backcolor.text).intValue()); :} | tCONST:s assignstmtlist:sl tNEWLINE {: RESULT=new ConstStmt(s.lineBegin, s.charBegin, sl); :} | tDATA:s explist:elist tNEWLINE {: RESULT=new DataStmt(s.lineBegin, s.charBegin, elist); :} | tDEF:s tSEG tASSIGN exp:e tNEWLINE {: RESULT=new DefsegStmt(s.lineBegin, s.charBegin, e); :} | tDO:s tNEWLINE stmtlist:sl tLOOP tNEWLINE {: RESULT=new DoStmt(s.lineBegin, s.charBegin, null, false, sl); :} | tDO:s tNEWLINE stmtlist:sl tLOOP tWHILE exp:e tNEWLINE {: RESULT=new DoStmt(s.lineBegin, s.charBegin, e, true, sl); :} | tDO:s tNEWLINE stmtlist:sl tLOOP tUNTIL exp:e tNEWLINE {: RESULT=new DoStmt(s.lineBegin, s.charBegin, e, false, sl); :} | forstmt:s {: RESULT=s; :} | tEND:s tNEWLINE {: RESULT=new EndStmt(s.lineBegin, s.charBegin, s.text); :} | tGET:s tLPAREN exp:x1 tCOMMA exp:y1 tRPAREN tMINUS tLPAREN exp:x2 tCOMMA exp:y2 tRPAREN tCOMMA var:varray {: RESULT=new GetGrfxStmt(s.lineBegin, s.charBegin,x1,y1,x2,y1,varray); :} | tLINE:s tLPAREN exp:x1 tCOMMA exp:y1 tRPAREN tMINUS tLPAREN exp:x2 tCOMMA exp:y2 tRPAREN {: RESULT=new LineStmt(s.lineBegin, s.charBegin, x1, y1, x2, y2, null, null, null, false, false); :} | tLINE:s tLPAREN exp:x1 tCOMMA exp:y1 tRPAREN tMINUS tLPAREN exp:x2 tCOMMA exp:y2 tRPAREN tCOMMA exp:color {: RESULT=new LineStmt(s.lineBegin, s.charBegin, x1, y1, x2, y2, color, null, null, false, false); :} | tLOCATE:s explist:optlist tNEWLINE {: RESULT=new LocateStmt(s.lineBegin, s.charBegin, optlist); :} | tMETASTATIC:s {: RESULT=new MetaStaticStmt(s.lineBegin, s.charBegin); :} | tMETADYNAMIC:s {: RESULT=new MetaDynamicStmt(s.lineBegin, s.charBegin); :} | tMETAINCLUDE:s tINCLUDEFILE:filename {: RESULT=new MetaIncludeStmt(s.lineBegin, s.charBegin, filename.text); :} | tOPTION:s tBASE exp:num tNEWLINE {: RESULT=new OptionBaseStmt(s.lineBegin, s.charBegin, num); :} | tOUT:s exp:portnum tCOMMA exp:value tNEWLINE {: RESULT=new OutStmt(s.lineBegin, s.charBegin, portnum, value); :} | tPSET:s tLPAREN exp:x tCOMMA exp:y tRPAREN tNEWLINE {: RESULT=new PsetStmt(s.lineBegin, s.charBegin, x,y,null,false); :} | tPSET:s tLPAREN exp:x tCOMMA exp:y tRPAREN tCOMMA exp:c tNEWLINE {: RESULT=new PsetStmt(s.lineBegin, s.charBegin, x,y,c,false); :} | tPSET:s tSTEP tLPAREN exp:x tCOMMA exp:y tRPAREN tCOMMA exp:c tNEWLINE {: RESULT=new PsetStmt(s.lineBegin, s.charBegin, x,y,c,true); :} | tPOKE:s exp:address tCOMMA exp:value tNEWLINE {: RESULT=new PokeStmt(s.lineBegin, s.charBegin, address, value); :} | tPRINT:s tNEWLINE {: RESULT=new PrintStmt(s.lineBegin, s.charBegin, new StringExp(s.lineBegin, s.charBegin,"")); :} | tPRINT:s stringexp:str tNEWLINE {: RESULT=new PrintStmt(s.lineBegin, s.charBegin, str); :} | tPUT:s tLPAREN exp:x tCOMMA exp:y tRPAREN tCOMMA var:v tNEWLINE {: RESULT=new PutGrfxStmt(s.lineBegin, s.charBegin, x, y,v, PutGrfxStmt.PSET); :} | tPUT:s tLPAREN exp:x tCOMMA exp:y tRPAREN tCOMMA var:v tCOMMA tPSET tNEWLINE {: RESULT=new PutGrfxStmt(s.lineBegin, s.charBegin, x, y,v, PutGrfxStmt.PSET); :} | tPUT:s tLPAREN exp:x tCOMMA exp:y tRPAREN tCOMMA var:v tCOMMA tOR tNEWLINE {: RESULT=new PutGrfxStmt(s.lineBegin, s.charBegin, x, y,v, PutGrfxStmt.OR); :} | tPUT:s tLPAREN exp:x tCOMMA exp:y tRPAREN tCOMMA var:v tCOMMA tXOR tNEWLINE {: RESULT=new PutGrfxStmt(s.lineBegin, s.charBegin, x, y,v, PutGrfxStmt.XOR); :} | tPUT:s tLPAREN exp:x tCOMMA exp:y tRPAREN tCOMMA var:v tCOMMA tAND tNEWLINE {: RESULT=new PutGrfxStmt(s.lineBegin, s.charBegin, x, y,v, PutGrfxStmt.AND); :} | tRANDOMIZE:s exp:seed tNEWLINE {: RESULT=new RandomizeStmt(s.lineBegin, s.charBegin, seed); :} | tREAD:s varlist:vlist tNEWLINE {: RESULT=new ReadStmt(s.lineBegin, s.charBegin, vlist); :} | tSELECT:s tCASE exp:testexp tNEWLINE caselist:clist tENDSELECT tNEWLINE {: RESULT=new SelectStmt(s.lineBegin, s.charBegin, testexp, clist); :} | tRESTORE:s tNEWLINE {: RESULT=new RestoreStmt(s.lineBegin, s.charBegin,null); :} | tRESTORE:s tVAR:label tNEWLINE {: /* should allow numerical linelabels too */ RESULT=new RestoreStmt(s.lineBegin, s.charBegin,label.text); :} | tSCREEN:s exp:modenum tNEWLINE {: RESULT=new ScreenStmt(s.lineBegin, s.charBegin, modenum); :} | tSLEEP:s tNEWLINE {: RESULT=new SleepStmt(s.lineBegin, s.charBegin, null); :} | tSLEEP:s exp:seconds tNEWLINE {: RESULT=new SleepStmt(s.lineBegin, s.charBegin, seconds); :} | tSWAP:s var:v1 tCOMMA var:v2 tNEWLINE {: RESULT=new SwapStmt(s.lineBegin, s.charBegin, v1, v2); :} | tWHILE:s exp:testexp tNEWLINE stmtlist:body tWEND tNEWLINE {: RESULT=new WhileStmt(s.lineBegin, s.charBegin, testexp, body); :} | tWIDTH:s exp:cols tCOMMA exp:rows tNEWLINE {: RESULT=new WidthStmt(s.lineBegin, s.charBegin, cols, rows); :} | tWIDTH:s exp:cols tNEWLINE {: RESULT=new WidthStmt(s.lineBegin, s.charBegin, cols, null); :} | tWIDTH:s tCOMMA exp:rows tNEWLINE {: RESULT=new WidthStmt(s.lineBegin, s.charBegin, null, rows); :} | subcallstmt:s {: RESULT=s; :} | assignstmt:s {: RESULT=s; :} | dimstmt:s {: RESULT=s; :} | redimstmt:s {: RESULT=s; :} | declaresubstmt:s {: RESULT=s; :} | declarefuncstmt:s {: RESULT=s; :} | ifstmt:s {: RESULT=s; :} | inputstmt:s {: RESULT=s; :} | typedecl:t tNEWLINE {: RESULT=new DeclStmt(t.lineBegin, t.charBegin, t); :} | tNEWLINE:s {: RESULT=new NoopStmt(s.lineBegin, s.charBegin); :} | error tNEWLINE:s {: System.err.println("Parse error detected on line "+(s.lineBegin+1)); :} ; casestmt::= tCASE:s explist:elist tNEWLINE stmtlist:slist {: RESULT=new CaseStmt(s.lineBegin, s.charBegin, elist,slist,false); :} | tCASE:s tELSE tNEWLINE stmtlist:slist {: RESULT=new CaseStmt(s.lineBegin, s.charBegin, null,slist,true); :} ; dimstmt::= tDIM:s varlist:v tNEWLINE {: RESULT=new DimStmt(s.lineBegin, s.charBegin,v,false,null); :} | tDIM:s varlist:v asexp:asType tNEWLINE {: /* this only works if the last variable has an asExp and assumes all of them do .. need to FIXME */ RESULT=new DimStmt(s.lineBegin, s.charBegin,v,false,asType); :} | tDIM:s tSHARED varlist:v asexp:asType tNEWLINE {: RESULT=new DimStmt(s.lineBegin, s.charBegin,v,true,asType); :} | tDIM:s tSHARED varlist:v tNEWLINE {: RESULT=new DimStmt(s.lineBegin, s.charBegin,v,true,null); :} ; redimstmt::= tREDIM:s varlist:v tNEWLINE {: RESULT=new RedimStmt(s.lineBegin, s.charBegin,v,false,null); :} | tREDIM:s varlist:v asexp:asType tNEWLINE {: RESULT=new RedimStmt(s.lineBegin, s.charBegin,v,false,asType); :} | tREDIM:s tSHARED varlist:v asexp:asType tNEWLINE {: RESULT=new RedimStmt(s.lineBegin, s.charBegin,v,true,asType); :} | tREDIM:s tSHARED varlist:v tNEWLINE {: RESULT=new RedimStmt(s.lineBegin, s.charBegin,v,true,null); :} ; inputstmt::= tINPUT:s tSEMI varlist:v tNEWLINE {: RESULT = new InputStmt(s.lineBegin, s.charBegin, null, v, true); :} | tINPUT:s stringexp:str tSEMI varlist:v tNEWLINE {: RESULT = new InputStmt(s.lineBegin, s.charBegin, str, v, true); :} | tINPUT:s tSEMI stringexp:str tSEMI varlist:v tNEWLINE {: RESULT = new InputStmt(s.lineBegin, s.charBegin, str, v, true); :} | tINPUT:s tCOMMA varlist:v tNEWLINE {: RESULT = new InputStmt(s.lineBegin, s.charBegin, null, v, false); :} | tINPUT:s stringexp:str tCOMMA varlist:v tNEWLINE {: RESULT = new InputStmt(s.lineBegin, s.charBegin, str, v, false); :} | tINPUT:s tSEMI stringexp:str tCOMMA varlist:v tNEWLINE {: RESULT = new InputStmt(s.lineBegin, s.charBegin, str, v, false); :} ; declaresubstmt::= tDECLARE:s tSUB var:v tNEWLINE {: RESULT=new DeclareSubStmt(s.lineBegin, s.charBegin,v); :} | tDECLARE:s tSUB smpvar:v tLPAREN tRPAREN tNEWLINE {: RESULT=new DeclareSubStmt(s.lineBegin, s.charBegin,v); :} ; declarefuncstmt::= tDECLARE:s tFUNCTION var:v tNEWLINE {: RESULT=new DeclareFuncStmt(s.lineBegin, s.charBegin,v); :} | tDECLARE:s tFUNCTION var:v tLPAREN tRPAREN tNEWLINE {: /* was smpvar */ RESULT=new DeclareSubStmt(s.lineBegin, s.charBegin,v); :} ; forstmt::= tFOR:s var:v tASSIGN exp:start tTO exp:end tNEWLINE:w stmtlist:body tNEXT tNEWLINE {: RESULT=new ForStmt(s.lineBegin, s.charBegin, v, start, end, new NumberExp(w.lineBegin, w.charBegin,"1"), body); :} | tFOR:s var:v tASSIGN exp:start tTO exp:end tNEWLINE:w stmtlist:body tNEXT var:r tNEWLINE {: RESULT=new ForStmt(s.lineBegin, s.charBegin, v, start, end, new NumberExp(w.lineBegin, w.charBegin,"1"), body); :} | tFOR:s var:v tASSIGN exp:start tTO exp:end tSTEP exp:step tNEWLINE stmtlist:body tNEXT tNEWLINE {: RESULT=new ForStmt(s.lineBegin, s.charBegin, v, start, end, step, body); :} | tFOR:s var:v tASSIGN exp:start tTO exp:end tSTEP exp:step tNEWLINE stmtlist:body tNEXT var:r tNEWLINE {: RESULT=new ForStmt(s.lineBegin, s.charBegin, v, start, end, step, body); :} ; stvardecl::=tVAR:v asexp:a {: RESULT=new VarDecl(v.lineBegin, v.charBegin, v.text, a); :} ; farrvardecl::=tVAR:v tLPAREN tRPAREN asexp:a {: /* FIXME: need to set flag indicating array var.*/ /* looks like spritearray() AS PointType */ RESULT=new VarDecl(v.lineBegin, v.charBegin, v.text, a); :} ; fvardecl::= stvardecl:stvar {: RESULT=stvar; :} | farrvardecl:farrvar {: RESULT=farrvar; :} | sngvar:v {: RESULT=new VarDecl(v.lineBegin, v.charBegin, v); :} | dblvar:v {: RESULT=new VarDecl(v.lineBegin, v.charBegin, v); :} | lngvar:v {: RESULT=new VarDecl(v.lineBegin, v.charBegin, v); :} | intvar:v {: RESULT=new VarDecl(v.lineBegin, v.charBegin, v); :} | strvar:v {: RESULT=new VarDecl(v.lineBegin, v.charBegin, v); :} | tNEWLINE:s {: RESULT=new VarDecl(s.lineBegin, s.charBegin,null); :} ; farglist::= farglist:flist tCOMMA fvardecl:fvar {: RESULT=flist.append(fvar); :} | fvardecl:fvar {: RESULT=new FrmlArgList(fvar); :} ; typelist::= typelist:tlist tNEWLINE stvardecl:stvar {: RESULT=tlist.append(stvar); :} | stvardecl:stvar {: RESULT=new DeclList(stvar); :} ; typedecl::= tTYPE:s tVAR:t tNEWLINE typelist:tlist tNEWLINE tEND tTYPE {: RESULT=new TypeDecl(s.lineBegin, s.charBegin, t.text,tlist); :} ;