構文木からAST(2)

タプルからASTに変換するプログラムを書いてみました。
今回は大部分のステートメントに対応しています。
エラー出力をどうするかの問題がありますが、とりあえず、構文木→抽象構文木の変換がどのようにやれば出来るのかが明確になったと思います。

以下ソース

package t2ast

object AST {

	abstract sealed class TypeDescriptor
		case class PrimitiveType(kind: PrimitiveTypeKind) extends TypeDescriptor
		case class ReferenceType(name: String, qualified: Boolean) extends TypeDescriptor
		case class ParameterizedType(component: TypeDescriptor, params: List[TypeDescriptor]) extends TypeDescriptor
		case class ArrayType(component: TypeDescriptor) extends TypeDescriptor

	abstract sealed class PrimitiveTypeKind
		case object KByte extends PrimitiveTypeKind
		case object KShort extends PrimitiveTypeKind
		case object KInt extends PrimitiveTypeKind
		case object KLong extends PrimitiveTypeKind
		case object KChar extends PrimitiveTypeKind
		case object KFloat extends PrimitiveTypeKind
		case object KDouble extends PrimitiveTypeKind
		case object KBoolean extends PrimitiveTypeKind
		case object KVoid extends PrimitiveTypeKind


	case class Position(line: Int, column: Int)
	abstract sealed class Node{ def pos: Position }
		case class TypeNode(pos: Position, desc: TypeDescriptor) extends Node
		case class Argument(pos: Position, name: String, typeRef: TypeNode) extends Node

		abstract sealed class Expression extends Node
			case class IntegerLiteral(pos: Position, value: Int) extends Expression
			case class Id(pos: Position, name: String) extends Expression
			case class NullLiteral(pos: Position) extends Expression
			case class BooleanLiteral(pos: Position, value: Boolean) extends Expression

			case class Cast(pos: Position, src: Expression, to: TypeNode) extends Expression
			case class CharacterLiteral(pos: Position, value: Char) extends Expression
			//case class ClosureExpression(pos: Position, typeRef: TypeNode, args: Argument, returns: TypeNode) extends Expression
			case class CurrentInstance(pos: Position) extends Expression
			case class DoubleLiteral(pos: Position, value: Double) extends Expression
			case class FloatLiteral(pos: Position, value: Float) extends Expression
			case class IsInstance(pos: Position, typeRef: TypeNode) extends Expression
			case class ListLiteral(pos: Position, elements: List[Expression]) extends Expression
			case class LongLiteral(pos: Position, value: Long) extends Expression
			case class MemberSelection(pos: Position, target: Expression, name: String) extends Expression
			case class MethodCall(pos: Position, target: Expression, name: String, args: List[Expression]) extends Expression
			case class NewArray(pos: Position, typeRef: TypeNode, args: List[Expression]) extends Expression
			case class NewObject(pos: Position, typeRef: TypeNode, args: List[Expression]) extends Expression
			case class UnqualifiedFieldReference(pos: Position, name: String) extends Expression
			case class UnqualifiedMethodCall(pos: Position, name: String, args: Expression) extends Expression
			case class StaticIDExpression(pos: Position, typeRef: TypeNode, name: String) extends Expression
			case class StaticMethodCall(pos: Position, typeRef: TypeNode, name: String, args: List[Expression]) extends Expression
			case class StringLiteral(pos: Position, value: String) extends Expression
			case class SuperMethodCall(pos: Position, name: String, args: List[Expression]) extends Expression


			abstract sealed class BinaryExpression(symbol: String) extends Expression {
				def left: Expression
				def right: Expression
			}
				case class Addition(pos: Position, left: Expression, right: Expression) extends BinaryExpression("+")
				case class Division(pos: Position, left: Expression, right: Expression) extends BinaryExpression("/")
				case class Multiplication(pos: Position, left: Expression, right: Expression) extends BinaryExpression("*")
				case class Subtraction(pos: Position, left: Expression, right: Expression) extends BinaryExpression("-")

				case class AdditionAssignment(pos: Position, left: Expression, right: Expression) extends BinaryExpression("+=")
				case class Assignment(pos: Position, left: Expression, right: Expression) extends BinaryExpression("=")
				case class BitAnd(pos: Position, left: Expression, right: Expression) extends BinaryExpression("&")
				case class BitOr(pos: Position, left: Expression, right: Expression) extends BinaryExpression("|")
				case class DivisionAssignment(pos: Position, left: Expression, right: Expression) extends BinaryExpression("/=")
				case class Elvis(pos: Position, left: Expression, right: Expression) extends BinaryExpression(":?")
				case class Equal(pos: Position, left: Expression, right: Expression) extends BinaryExpression("==")
				case class GreaterOrEqual(pos: Position, left: Expression, right: Expression) extends BinaryExpression(">=")
				case class GreaterThan(pos: Position, left: Expression, right: Expression) extends BinaryExpression(">")
				case class Indexing(pos: Position, left: Expression, right: Expression) extends BinaryExpression("[]")
				case class LessOrEqual(pos: Position, left: Expression, right: Expression) extends BinaryExpression("<=")
				case class LessThan(pos: Position, left: Expression, right: Expression) extends BinaryExpression("<")  
				case class LogicalAnd(pos: Position, left: Expression, right: Expression) extends BinaryExpression("&&")
				case class LogicalOr(pos: Position, left: Expression, right: Expression) extends BinaryExpression("||")
				case class LogicalRightShift(pos: Position, left: Expression, right: Expression) extends BinaryExpression(">>>")
				case class MathLeftShift(pos: Position, left: Expression, right: Expression) extends BinaryExpression("<<")
				case class MathRightShift(pos: Position, left: Expression, right: Expression) extends BinaryExpression(">>")
				case class Modulo(pos: Position, left: Expression, right: Expression) extends BinaryExpression("%")
				case class ModuloAssignment(pos: Position, left: Expression, right: Expression) extends BinaryExpression("%=")
				case class MultiplicationAssignment(pos: Position, left: Expression, right: Expression) extends BinaryExpression("*=")
				case class NotEqual(pos: Position, left: Expression, right: Expression) extends BinaryExpression("!=")
				case class SubtractionAssignment(pos: Position, left: Expression, right: Expression) extends BinaryExpression("-=")
				case class XOR(pos: Position, left: Expression, right: Expression) extends BinaryExpression("^")
				case class ReferenceEqual(pos: Position, left: Expression, right: Expression) extends BinaryExpression("===")
				case class ReferenceNotEqual(pos: Position, left: Expression, right: Expression) extends BinaryExpression("!==")

			abstract sealed class UnaryExpression(symbol: String) extends Expression {
				def target: Expression
			}
				case class Negate(pos: Position, target: Expression) extends UnaryExpression("-")
				case class Not(pos: Position, target: Expression) extends UnaryExpression("!")
				case class Posit(pos: Position, target: Expression) extends UnaryExpression("+")
				case class PostDecrement(pos: Position, target: Expression) extends UnaryExpression("--")
				case class PostIncrement(pos: Position, target: Expression) extends UnaryExpression("++")


		abstract sealed class Toplevel extends Node

			abstract sealed class Statement extends Toplevel
				case class BlockStatement(pos: Position, elements: List[Statement]) extends Statement
				case class BreakStatement(pos: Position) extends Statement
				case class ContinueStatement(pos: Position) extends Statement
				case class EmptyStatement(pos: Position) extends Statement
				case class IfStatement(pos: Position, condition: Expression, thenBlock: BlockStatement, elseBlock: BlockStatement) extends Statement
				case class ReturnStatement(pos: Position) extends Statement
				case class LocalVariableDeclaration(pos: Position, name: String, typeRef: TypeNode, init: Expression) extends Statement
				case class WhileStatement(pos: Position, condition: Expression, block: BlockStatement) extends Statement
				case class SynchronizedStatement(pos: Position, condition: Expression, block: BlockStatement) extends Statement
				case class ThrowStatement(pos: Position, target: Expression) extends Statement
				case class ForeachStatement(pos: Position, arg: Argument, collection: Expression, statement: BlockStatement) extends Statement
				case class ForStatement(pos: Position, init: Statement, condition: Expression, update: Expression, block: BlockStatement) extends Statement
				case class CondStatement(pos: Position, clauses: List[(Expression, BlockStatement)], elseBlock: Option[BlockStatement]) extends Statement
				// todo elseblock
				case class SelectStatement(pos: Position, condition: Expression, cases: List[(List[Expression], BlockStatement)]) extends Statement
				case class TryStatement(pos: Position, tryBlock: BlockStatement, recClauses: List[(Argument, BlockStatement)], finBlock: Option[BlockStatement]) extends Statement
				// todo finaryblock
				case class ExpressionStatement(pos: Position, body: Expression) extends Statement
}

object main {
	def arg(a:Any):AST.Argument = a match {
	case (l:Int,c:Int,(_,_,a:String),":",t) => AST.Argument(AST.Position(l,c),a,typenode(t))
	}
	def typenode(a:Any):AST.TypeNode = a match {
		case (l:Int,c:Int,"byte") => AST.TypeNode(AST.Position(l,c),AST.PrimitiveType(AST.KByte))
		case (l:Int,c:Int,"short") => AST.TypeNode(AST.Position(l,c),AST.PrimitiveType(AST.KShort))
		case (l:Int,c:Int,"int") => AST.TypeNode(AST.Position(l,c),AST.PrimitiveType(AST.KInt))
		case (l:Int,c:Int,"long") => AST.TypeNode(AST.Position(l,c),AST.PrimitiveType(AST.KLong))
		case (l:Int,c:Int,"char") => AST.TypeNode(AST.Position(l,c),AST.PrimitiveType(AST.KChar))
		case (l:Int,c:Int,"float") => AST.TypeNode(AST.Position(l,c),AST.PrimitiveType(AST.KFloat))
		case (l:Int,c:Int,"double") => AST.TypeNode(AST.Position(l,c),AST.PrimitiveType(AST.KDouble))
		case (l:Int,c:Int,"boolean") => AST.TypeNode(AST.Position(l,c),AST.PrimitiveType(AST.KBoolean))
		case (l:Int,c:Int,a,"[",(_,_,"void"),"]") => val n = typenode(a:Any); AST.TypeNode(AST.Position(l,c),AST.ArrayType(n.desc))
		case (l:Int,c:Int,a:String) => val quarify = true; AST.TypeNode(AST.Position(l,c),AST.ReferenceType(a, quarify))
	}
	def caseblocks(a:Any):List[(AST.Expression, AST.BlockStatement)] = a match {
		case (l:Int,c:Int,"case","(",a,")",b) => List((exp(a),blockstatement(b)))
		case (l:Int,c:Int,a,"@",b) => caseblocks(a):::caseblocks(b)
	}
	def casesblocks(a:Any):List[(List[AST.Expression], AST.BlockStatement)] = a match {
		case (l:Int,c:Int,"case","(",a,")",b) => List((exps(a),blockstatement(b)))
		case (l:Int,c:Int,a,"@",b) => casesblocks(a):::casesblocks(b)
	}
	def exps(a:Any):List[AST.Expression] = a match {
		case (l:Int,c:Int,a,",",b) => exps(a):::exps(b)
		case a => List(exp(a))
	}
	def catchblocks(a:Any):List[(AST.Argument, AST.BlockStatement)] = a match {
		case (l:Int,c:Int,"case","(",a,")",b) => List((arg(a),blockstatement(b)))
		case (l:Int,c:Int,a,"@",b) => catchblocks(a):::catchblocks(b)
	}

	def top(a:Any):AST.Toplevel = statement(a)
	def statement(a:Any):AST.Statement = a match {
		case (l:Int,c:Int,"{",a,"}") => AST.BlockStatement(AST.Position(l,c), statements(a))
		case (l:Int,c:Int,"break") => AST.BreakStatement(AST.Position(l,c))
		case (l:Int,c:Int,"continue") => AST.ContinueStatement(AST.Position(l,c))
		case (l:Int,c:Int,"return") => AST.ReturnStatement(AST.Position(l,c))
		case (l:Int,c:Int,"void") => AST.EmptyStatement(AST.Position(l,c))
		case (l:Int,c:Int,a,";") => statement(a)
		case (l:Int,c:Int,"throw",a) => AST.ThrowStatement(AST.Position(l,c), exp(a))
		case (l:Int,c:Int,"if","(",a,")",(_,_,x,"else",y)) =>
			AST.IfStatement(AST.Position(l,c), exp(a), blockstatement(x), blockstatement(y))
		case (l:Int,c:Int,"if","(",a,")",b) =>
			AST.IfStatement(
				AST.Position(l, c),
				exp(a),
				blockstatement(b),
				AST.BlockStatement(AST.Position(l,c),List(AST.EmptyStatement(AST.Position(l,c))))
			)
		case (l:Int,c:Int,"while","(",a,")",b) =>
			AST.WhileStatement(
				AST.Position(l, c),
				exp(a),
				blockstatement(b))

		case (l:Int,c:Int,(_,_,a:String),":",(_,_,t,"=",x)) => AST.LocalVariableDeclaration(AST.Position(l,c), a, typenode(t), exp(x))
		case (l:Int,c:Int,(_,_,a:String),":",t) => AST.LocalVariableDeclaration(AST.Position(l,c), a, typenode(t), AST.NullLiteral(AST.Position(l,c)))
		case (l:Int,c:Int,"synchronized","(",a,")",b) =>
			AST.SynchronizedStatement(
				AST.Position(l, c),
				exp(a),
				blockstatement(b))
		case (l:Int,c:Int,"foreach","(",(_,_,a,"<-",b),")",x) =>
			AST.ForeachStatement(
				AST.Position(l, c),
				arg(a),
				exp(b),
				blockstatement(x))
		case (l:Int,c:Int,"for","(",a,")",d) =>
			a match {
			case (_,_,a2,"@",(_,_,(_,_,b,";"),"@",x)) =>
				AST.ForStatement(AST.Position(l,c), statement(a2), exp(b), exp(x),blockstatement(d))
			case _ => throw new Exception("error for statements " + a)
			}
		case (l:Int,c:Int,(_,_,"cond"), "{",d,"}") => val cb = caseblocks(d); AST.CondStatement(AST.Position(l,c), cb, None)
		case (l:Int,c:Int,"select","(",a,")", (_,_,"{",d,"}")) => val cb = casesblocks(d); AST.SelectStatement(AST.Position(l,c), exp(a), cb)
		case (l:Int,c:Int,"try","{",a,"}", (_,_,(_,_,"catch"),"{",d,"}")) =>
			val cb = catchblocks(d);
			AST.TryStatement(AST.Position(l,c), blockstatement((l,c,"{",a,"}")), cb, None)

		case a => val e = exp(a); AST.ExpressionStatement(e.pos, e)
//		case _ => throw new Exception("error " + a)
	}

	def blockstatement(a:Any):AST.BlockStatement = a match {
		case (l:Int,c:Int,"{",a,"}") => AST.BlockStatement(AST.Position(l,c), statements(a))
		case _ => throw new Exception("error " + a)
	}

	def statements(a:Any):List[AST.Statement] = a match {
		case (l:Int,c:Int,a,"@",b) => statements(a):::statements(a)
		case a => List(statement(a))
	}

	def exp(a:Any):AST.Expression = a match {
		case (l:Int,c:Int,a:Int) => AST.IntegerLiteral(AST.Position(l,c), a)
		case (l:Int,c:Int,a:Boolean) => AST.BooleanLiteral(AST.Position(l,c), a)
		case (l:Int,c:Int,a:Char) => AST.CharacterLiteral(AST.Position(l,c), a)
		case (l:Int,c:Int,a:Double) => AST.DoubleLiteral(AST.Position(l,c), a)
		case (l:Int,c:Int,a:Float) => AST.DoubleLiteral(AST.Position(l,c), a)
		case (l:Int,c:Int,a:Long) => AST.LongLiteral(AST.Position(l,c), a)
		case (l:Int,c:Int,"this") => AST.CurrentInstance(AST.Position(l,c))
		case (l:Int,c:Int,a:String) => AST.Id(AST.Position(l,c), a)
		case (l:Int,c:Int,"cast","(",t,")",e) => AST.Cast(AST.Position(l,c), exp(e), typenode(t))
		case (l:Int,c:Int,a,"instanceof", b) => AST.IsInstance(AST.Position(l,c), typenode(b))// todo おかしくね?
		case (l:Int,c:Int,(_,_,"List"),"(",a,")") => AST.ListLiteral(AST.Position(l,c), exps(a))
		case (l:Int, c:Int, (_,_,"super"), ".", (_,_,(_,_,b:String),"(",x,")")) => AST.SuperMethodCall(AST.Position(l,c), b,exps(x))
		case (l:Int, c:Int, a, ".", (_,_,(_,_,b:String),"(",x,")")) => AST.MethodCall(AST.Position(l,c), exp(a), b,exps(x))
		case (l:Int, c:Int, a, ".", (_,_,b:String)) => AST.MemberSelection(AST.Position(l,c), exp(a), b)
		case (l:Int, c:Int, "new" ,(_,_,t,"[",a,"]")) => AST.NewArray(AST.Position(l,c), typenode(t), exps(a))
		case (l:Int, c:Int, "new", (_,_,t,"(",a,")"))=> AST.NewObject(AST.Position(l,c), typenode(t), exps(a))
//		case (l:Int, c:Int, ))  //  UnqualifiedFieldReference
//		case (l:Int, c:Int, ))  //  UnqualifiedMethodCall
//		case (l:Int, c:Int, ))  //  StaticIDExpression
//		case (l:Int, c:Int, ))  //  StaticMethodCall
//		case (l:Int, c:Int, ))  //  StringLiteral

		
		case (_,_,_,_,_) => bin(a)
		case (_,_,_,_) => unary(a)
		case _ => throw new Exception("expected expression but found " + a)
	}

	def bin(a:Any):AST.BinaryExpression = a match {
		case (l:Int, c:Int, a, "+", b) => AST.Addition(AST.Position(l,c), exp(a), exp(b))
		case (l:Int, c:Int, a, "-", b) => AST.Division(AST.Position(l,c), exp(a), exp(b))
		case (l:Int, c:Int, a, "*", b) => AST.Multiplication(AST.Position(l,c), exp(a), exp(b))
		case (l:Int, c:Int, a, "/", b) => AST.Subtraction(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, "+=", b) => AST.AdditionAssignment(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, "=", b) => AST.Assignment(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, "&", b) => AST.BitAnd(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, "|", b) => AST.BitOr(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, "/=", b) => AST.DivisionAssignment(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, ":?", b) => AST.Elvis(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, "==", b) => AST.Equal(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, ">=", b) => AST.GreaterOrEqual(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, ">", b) => AST.GreaterThan(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, "[]", b) => AST.Indexing(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, "<=", b) => AST.LessOrEqual(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, "<", b) => AST.LessThan(AST.Position(l,c), exp(a), exp(b))  
        case (l:Int, c:Int, a, "&&", b) => AST.LogicalAnd(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, "||", b) => AST.LogicalOr(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, ">>>", b) => AST.LogicalRightShift(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, "<<", b) => AST.MathLeftShift(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, ">>", b) => AST.MathRightShift(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, "%", b) => AST.Modulo(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, "%=", b) => AST.ModuloAssignment(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, "*=", b) => AST.MultiplicationAssignment(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, "!=", b) => AST.NotEqual(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, "-=", b) => AST.SubtractionAssignment(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, "^", b) => AST.XOR(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, "===", b) => AST.ReferenceEqual(AST.Position(l,c), exp(a), exp(b))
        case (l:Int, c:Int, a, "!==", b) => AST.ReferenceNotEqual(AST.Position(l,c), exp(a), exp(b))

		case _ => throw new Exception("expected binary expression but found " + a)
	}

	def unary(a:Any):AST.UnaryExpression = a match {
		case (l:Int,c:Int,"-",a) => AST.Negate(AST.Position(l,c), exp(a))
		case (l:Int,c:Int,"!",a) => AST.Not(AST.Position(l,c), exp(a))
		case (l:Int,c:Int,"+",a) => AST.Posit(AST.Position(l,c), exp(a))
		case (l:Int,c:Int,"--",a) => AST.PostDecrement(AST.Position(l,c), exp(a))
		case (l:Int,c:Int,"++",a) => AST.PostIncrement(AST.Position(l,c), exp(a))
		case _ => throw new Exception("expected unary expression but found " + a)
	}

	def test(a:Any) {
		val r = exp(p(a))
		println(a + "=>" + r)
	}

	def testtop(a:Any) {
		println(a +"=>")
		val b = p(a)
		println(b +"=>")
		val r = top(b)
		println(""+r)
	}

	def p(a:Any):Any = a match {
		case ("{",a,"}") => (0,0,"{",p(a),"}")
		case ("(",a,")") => (0,0,"(",p(a),")")
		case ("[",a,"]") => (0,0,"[",p(a),"]")
		case (a,"{",b,"}") => (0,0,p(a),"{",p(b),"}")
		case (a,"(",b,")") => (0,0,p(a),"(",p(b),")")
		case (a,"[",b,"]") => (0,0,p(a),"[",p(b),"]")
		case (a,"{",b,"}",c) => (0,0,a,"{",p(b),"}",p(c))
		case (a,"(",b,")",c) => (0,0,a,"(",p(b),")",p(c))
		case (a,"[",b,"]",c) => (0,0,a,"[",p(b),"]",p(c))
		case (a,";") => (0,0,p(a),";")
		case (a,b) =>(0,0,a,p(b))
		case (a,b,c) => (0,0,p(a),b,p(c))
		case a => (0,0,a)
	}

	def main(argv:Array[String]) {

		testtop((1))
		testtop((1,"+",2))
		testtop((1,"+",(2,"*",3)))

		testtop(("{","break","}"))
		testtop(("{",("break","@","break"),"}"))
		testtop((("{",("break","@","break"),"}"),";"))
		testtop((("{",(("break",";"),"@",("break",";")),"}"),";"))
		testtop((("{","continue","}"),";"))
		testtop((("{","void","}"),";"))
		testtop(("if","(",1,")",("{","void","}")))
		testtop(("if","(",1,")",("{","break","}")))
		testtop(("if","(",1,")",(("{","break","}"),"else",("{","break","}"))))
		testtop(("if","(",1,")",(("{","return","}"),"else",("{","return","}"))))
		testtop(("a",":","int"))
		testtop(("a",":",("int","=",1)))
		testtop(("a",":",("int","=",(1,"*",2))))
		testtop(("while","(",1,")",("{","break","}")))

		testtop(("a",":","byte"))
		testtop(("a",":","short"))
		testtop(("a",":","int"))
		testtop(("a",":","long"))
		testtop(("a",":","char"))
		testtop(("a",":","float"))
		testtop(("a",":","double"))
		testtop(("a",":","boolean"))
		testtop(("a",":",("byte","[","void","]")))
		testtop(("a",":",(("byte","[","void","]"),"[","void","]")))
		testtop(("a",":","Test"))
		testtop(("synchronized","(",1,")",("{","void","}")))
		testtop(("throw",1))
		testtop(("foreach","(",(("a",":","int"),"<-",1),")",("{","void","}")))

		val a4 = ((1,";"),"@",((2,";"),"@",3))
		testtop(("for","(", a4, ")",("{",1,"}")))
		testtop(("cond","{",("case","(",1,")",("{",2,"}")),"}" ))
		testtop(("select","(",1,")",("{",("case","(",2,")",("{",3,"}")),"}") ))
		testtop(("try","{","break","}",("catch","{",("case","(",("a",":","int"),")",("{",3,"}")),"}")))
		testtop(true)
		testtop(false)
		testtop(("cast","(","boolean",")",1))
		testtop('a')
		testtop("this")
		testtop(1.5d)
		testtop(1.5f)
		testtop(("1","instanceof", "Int")) // IsInstance
		testtop(("List","(","a",")"))  //  ListLiteral
		testtop((1L))  //  LongLiteral
		testtop(("a",".","b"))  //  MemberSelection
		testtop(("a",".",("b","(",1,")")))  //  MethodCall
		testtop(("new",("Int","[",1,"]")))  //  NewArray
		testtop(("new",("A","(",1,")")))  //  NewObject
//		testtop(())  //  UnqualifiedFieldReference
//		testtop(())  //  UnqualifiedMethodCall
//		testtop(())  //  StaticIDExpression
//		testtop(())  //  StaticMethodCall
//		testtop(())  //  StringLiteral
		testtop(("super",".",("a","(",1,")")))  //  SuperMethodCall

		testtop(("a", "+", "b"))  // Addition
		testtop(("a", "+=", "b"))  // AdditionAssignment
		testtop(("a", "=", "b"))  // Assignment
		testtop(("a", "&", "b"))  // BitAnd
		testtop(("a", "|", "b"))   // BitOr 
		testtop(("a", "/", "b"))   // Division 
		testtop(("a", "/=", "b"))   // DivisionAssignment 
		testtop(("a", ":?", "b"))   // Elvis 
		testtop(("a", "==", "b"))   // Equal 
		testtop(("a", ">=", "b"))   // GreaterOrEqual 
		testtop(("a", ">", "b"))   // GreaterThan 
		testtop(("a", "[]", "b"))   // Indexing 
		testtop(("a", "<=", "b"))   // LessOrEqual 
		testtop(("a", "<", "b"))   // LessThan   
		testtop(("a", "&&", "b"))   // LogicalAnd 
		testtop(("a", "||", "b"))   // LogicalOr 
		testtop(("a", ">>>", "b"))   // LogicalRightShift 
		testtop(("a", "<<", "b"))   // MathLeftShift 
		testtop(("a", ">>", "b"))   // MathRightShift 
		testtop(("a", "%", "b"))   // Modulo 
		testtop(("a", "%=", "b"))   // ModuloAssignment 
		testtop(("a", "*", "b"))   // Multiplication 
		testtop(("a", "*=", "b"))   // MultiplicationAssignment 
		testtop(("a", "!=", "b"))   // NotEqual 
		testtop(("a", "-", "b"))   // Subtraction 
		testtop(("a", "-=", "b"))   // SubtractionAssignment 
		testtop(("a", "^", "b"))   // XOR 
		testtop(("a", "===", "b"))   // ReferenceEqual 
		testtop(("a", "!==", "b"))   // ReferenceNotEqual 

		testtop(("-","a")) // Negate
		testtop(("!","a")) // Not
		testtop(("+","a")) // Posit
		testtop(("--","a")) // PostDecrement
		testtop(("++","a")) // PostIncrement

	}
}