%{ open Ast %} (* arithmetic and logical commands *) %token ADD SUB EQ GT LT AND OR NEG NOT (* memory commands *) %token POP PUSH (* memory segments *) %token CONSTANT STATIC POINTER TEMP ARGUMENT LOCAL THIS THAT (* branching commands *) %token LABEL GOTO IFGOTO (* function commands*) %token FUNCTION CALL RETURN %token ADDRESS %token ID %token COMMENT %token EOF %start prog %% prog: | e = expr; EOF { e } ; expr: | c = COMMENT { Comment c } | e = arithmetic { e } | POP; p = pop { p } | PUSH; p = push { p } | b = branching { b } | FUNCTION; f = function_definition { f } | CALL; c = function_call { c } | RETURN { Return } | e = expr; COMMENT { e } ; arithmetic: | ADD { ArithmeticCommand Add } | SUB { ArithmeticCommand Sub } | EQ { ArithmeticCommand Eq } | GT { ArithmeticCommand Gt } | LT { ArithmeticCommand Lt } | AND { ArithmeticCommand And } | OR { ArithmeticCommand Or } | NEG { ArithmeticCommand Neg } | NOT { ArithmeticCommand Not } ; pop: | ARGUMENT; a = ADDRESS { MemoryAccessCommand (Pop, Argument, a) } | LOCAL; a = ADDRESS { MemoryAccessCommand (Pop, Local, a) } | STATIC; a = ADDRESS { MemoryAccessCommand (Pop, Static, a) } | THIS; a = ADDRESS { MemoryAccessCommand (Pop, This, a) } | THAT; a = ADDRESS { MemoryAccessCommand (Pop, That, a) } | POINTER; a = ADDRESS { MemoryAccessCommand (Pop, Pointer, a) } | TEMP; a = ADDRESS { MemoryAccessCommand (Pop, Temp, a) } ; push: | ARGUMENT; a = ADDRESS { MemoryAccessCommand (Push, Argument, a) } | LOCAL; a = ADDRESS { MemoryAccessCommand (Push, Local, a) } | STATIC; a = ADDRESS { MemoryAccessCommand (Push, Static, a) } | THIS; a = ADDRESS { MemoryAccessCommand (Push, This, a) } | THAT; a = ADDRESS { MemoryAccessCommand (Push, That, a) } | POINTER; a = ADDRESS { MemoryAccessCommand (Push, Pointer, a) } | TEMP; a = ADDRESS { MemoryAccessCommand (Push, Temp, a) } | CONSTANT; a = ADDRESS { MemoryAccessCommand (Push, Constant, a) } ; branching: | LABEL; i = ID { ProgramFlowCommand (Label, i) } | GOTO; i = ID { ProgramFlowCommand (Goto, i) } | IFGOTO; i = ID { ProgramFlowCommand (Ifgoto, i) } ; function_definition: | i = ID; a = ADDRESS { FunctionCallCommand (Function, i, a) } ; function_call: | i = ID; a = ADDRESS { FunctionCallCommand (Call, i, a) } ;