Compilers: Principles and Practice