PRINCIPLES OF COMPILER DESIGN