New directory structure:
- simulator source now in 'src' subdirectory
- imported files from 'ext' repository
- support building in arbitrary places, including
outside of the source tree. See comment at top
of SConstruct file for more details.
Regression tests are temporarily disabled; that
syetem needs more extensive revisions.
SConstruct:
Update for new directory structure.
Modify to support build trees that are not subdirectories
of the source tree. See comment at top of file for
more details.
Regression tests are temporarily disabled.
src/arch/SConscript:
src/arch/isa_parser.py:
src/python/SConscript:
Update for new directory structure.
--HG--
rename : build/SConstruct => SConstruct
rename : build/default_options/ALPHA_FS => build_opts/ALPHA_FS
rename : build/default_options/ALPHA_FS_TL => build_opts/ALPHA_FS_TL
rename : build/default_options/ALPHA_SE => build_opts/ALPHA_SE
rename : build/default_options/MIPS_SE => build_opts/MIPS_SE
rename : build/default_options/SPARC_SE => build_opts/SPARC_SE
rename : Doxyfile => src/Doxyfile
rename : SConscript => src/SConscript
rename : arch/SConscript => src/arch/SConscript
rename : arch/alpha/SConscript => src/arch/alpha/SConscript
rename : arch/alpha/aout_machdep.h => src/arch/alpha/aout_machdep.h
rename : arch/alpha/arguments.cc => src/arch/alpha/arguments.cc
rename : arch/alpha/arguments.hh => src/arch/alpha/arguments.hh
rename : arch/alpha/ecoff_machdep.h => src/arch/alpha/ecoff_machdep.h
rename : arch/alpha/ev5.cc => src/arch/alpha/ev5.cc
rename : arch/alpha/ev5.hh => src/arch/alpha/ev5.hh
rename : arch/alpha/faults.cc => src/arch/alpha/faults.cc
rename : arch/alpha/faults.hh => src/arch/alpha/faults.hh
rename : arch/alpha/freebsd/system.cc => src/arch/alpha/freebsd/system.cc
rename : arch/alpha/freebsd/system.hh => src/arch/alpha/freebsd/system.hh
rename : arch/alpha/isa/branch.isa => src/arch/alpha/isa/branch.isa
rename : arch/alpha/isa/decoder.isa => src/arch/alpha/isa/decoder.isa
rename : arch/alpha/isa/fp.isa => src/arch/alpha/isa/fp.isa
rename : arch/alpha/isa/int.isa => src/arch/alpha/isa/int.isa
rename : arch/alpha/isa/main.isa => src/arch/alpha/isa/main.isa
rename : arch/alpha/isa/mem.isa => src/arch/alpha/isa/mem.isa
rename : arch/alpha/isa/opcdec.isa => src/arch/alpha/isa/opcdec.isa
rename : arch/alpha/isa/pal.isa => src/arch/alpha/isa/pal.isa
rename : arch/alpha/isa/unimp.isa => src/arch/alpha/isa/unimp.isa
rename : arch/alpha/isa/unknown.isa => src/arch/alpha/isa/unknown.isa
rename : arch/alpha/isa/util.isa => src/arch/alpha/isa/util.isa
rename : arch/alpha/isa_traits.hh => src/arch/alpha/isa_traits.hh
rename : arch/alpha/linux/aligned.hh => src/arch/alpha/linux/aligned.hh
rename : arch/alpha/linux/hwrpb.hh => src/arch/alpha/linux/hwrpb.hh
rename : arch/alpha/linux/linux.cc => src/arch/alpha/linux/linux.cc
rename : arch/alpha/linux/linux.hh => src/arch/alpha/linux/linux.hh
rename : arch/alpha/linux/process.cc => src/arch/alpha/linux/process.cc
rename : arch/alpha/linux/process.hh => src/arch/alpha/linux/process.hh
rename : arch/alpha/linux/system.cc => src/arch/alpha/linux/system.cc
rename : arch/alpha/linux/system.hh => src/arch/alpha/linux/system.hh
rename : arch/alpha/linux/thread_info.hh => src/arch/alpha/linux/thread_info.hh
rename : arch/alpha/linux/threadinfo.hh => src/arch/alpha/linux/threadinfo.hh
rename : arch/alpha/osfpal.cc => src/arch/alpha/osfpal.cc
rename : arch/alpha/osfpal.hh => src/arch/alpha/osfpal.hh
rename : arch/alpha/process.cc => src/arch/alpha/process.cc
rename : arch/alpha/process.hh => src/arch/alpha/process.hh
rename : arch/alpha/regfile.hh => src/arch/alpha/regfile.hh
rename : arch/alpha/stacktrace.cc => src/arch/alpha/stacktrace.cc
rename : arch/alpha/stacktrace.hh => src/arch/alpha/stacktrace.hh
rename : arch/alpha/system.cc => src/arch/alpha/system.cc
rename : arch/alpha/system.hh => src/arch/alpha/system.hh
rename : arch/alpha/tlb.cc => src/arch/alpha/tlb.cc
rename : arch/alpha/tlb.hh => src/arch/alpha/tlb.hh
rename : arch/alpha/tru64/process.cc => src/arch/alpha/tru64/process.cc
rename : arch/alpha/tru64/process.hh => src/arch/alpha/tru64/process.hh
rename : arch/alpha/tru64/system.cc => src/arch/alpha/tru64/system.cc
rename : arch/alpha/tru64/system.hh => src/arch/alpha/tru64/system.hh
rename : arch/alpha/tru64/tru64.cc => src/arch/alpha/tru64/tru64.cc
rename : arch/alpha/tru64/tru64.hh => src/arch/alpha/tru64/tru64.hh
rename : arch/alpha/types.hh => src/arch/alpha/types.hh
rename : arch/alpha/utility.hh => src/arch/alpha/utility.hh
rename : arch/alpha/vtophys.cc => src/arch/alpha/vtophys.cc
rename : arch/alpha/vtophys.hh => src/arch/alpha/vtophys.hh
rename : arch/isa_parser.py => src/arch/isa_parser.py
rename : arch/isa_specific.hh => src/arch/isa_specific.hh
rename : arch/mips/SConscript => src/arch/mips/SConscript
rename : arch/mips/faults.cc => src/arch/mips/faults.cc
rename : arch/mips/faults.hh => src/arch/mips/faults.hh
rename : arch/mips/isa/base.isa => src/arch/mips/isa/base.isa
rename : arch/mips/isa/bitfields.isa => src/arch/mips/isa/bitfields.isa
rename : arch/mips/isa/decoder.isa => src/arch/mips/isa/decoder.isa
rename : arch/mips/isa/formats/basic.isa => src/arch/mips/isa/formats/basic.isa
rename : arch/mips/isa/formats/branch.isa => src/arch/mips/isa/formats/branch.isa
rename : arch/mips/isa/formats/formats.isa => src/arch/mips/isa/formats/formats.isa
rename : arch/mips/isa/formats/fp.isa => src/arch/mips/isa/formats/fp.isa
rename : arch/mips/isa/formats/int.isa => src/arch/mips/isa/formats/int.isa
rename : arch/mips/isa/formats/mem.isa => src/arch/mips/isa/formats/mem.isa
rename : arch/mips/isa/formats/noop.isa => src/arch/mips/isa/formats/noop.isa
rename : arch/mips/isa/formats/tlbop.isa => src/arch/mips/isa/formats/tlbop.isa
rename : arch/mips/isa/formats/trap.isa => src/arch/mips/isa/formats/trap.isa
rename : arch/mips/isa/formats/unimp.isa => src/arch/mips/isa/formats/unimp.isa
rename : arch/mips/isa/formats/unknown.isa => src/arch/mips/isa/formats/unknown.isa
rename : arch/mips/isa/formats/util.isa => src/arch/mips/isa/formats/util.isa
rename : arch/mips/isa/includes.isa => src/arch/mips/isa/includes.isa
rename : arch/mips/isa/main.isa => src/arch/mips/isa/main.isa
rename : arch/mips/isa/operands.isa => src/arch/mips/isa/operands.isa
rename : arch/mips/isa_traits.cc => src/arch/mips/isa_traits.cc
rename : arch/mips/isa_traits.hh => src/arch/mips/isa_traits.hh
rename : arch/mips/linux/linux.cc => src/arch/mips/linux/linux.cc
rename : arch/mips/linux/linux.hh => src/arch/mips/linux/linux.hh
rename : arch/mips/linux/process.cc => src/arch/mips/linux/process.cc
rename : arch/mips/linux/process.hh => src/arch/mips/linux/process.hh
rename : arch/mips/process.cc => src/arch/mips/process.cc
rename : arch/mips/process.hh => src/arch/mips/process.hh
rename : arch/mips/regfile/float_regfile.hh => src/arch/mips/regfile/float_regfile.hh
rename : arch/mips/regfile/int_regfile.hh => src/arch/mips/regfile/int_regfile.hh
rename : arch/mips/regfile/misc_regfile.hh => src/arch/mips/regfile/misc_regfile.hh
rename : arch/mips/regfile/regfile.hh => src/arch/mips/regfile/regfile.hh
rename : arch/mips/stacktrace.hh => src/arch/mips/stacktrace.hh
rename : arch/mips/types.hh => src/arch/mips/types.hh
rename : arch/mips/utility.hh => src/arch/mips/utility.hh
rename : arch/sparc/SConscript => src/arch/sparc/SConscript
rename : arch/sparc/faults.cc => src/arch/sparc/faults.cc
rename : arch/sparc/faults.hh => src/arch/sparc/faults.hh
rename : arch/sparc/isa/base.isa => src/arch/sparc/isa/base.isa
rename : arch/sparc/isa/bitfields.isa => src/arch/sparc/isa/bitfields.isa
rename : arch/sparc/isa/decoder.isa => src/arch/sparc/isa/decoder.isa
rename : arch/sparc/isa/formats.isa => src/arch/sparc/isa/formats.isa
rename : arch/sparc/isa/formats/basic.isa => src/arch/sparc/isa/formats/basic.isa
rename : arch/sparc/isa/formats/branch.isa => src/arch/sparc/isa/formats/branch.isa
rename : arch/sparc/isa/formats/integerop.isa => src/arch/sparc/isa/formats/integerop.isa
rename : arch/sparc/isa/formats/mem.isa => src/arch/sparc/isa/formats/mem.isa
rename : arch/sparc/isa/formats/nop.isa => src/arch/sparc/isa/formats/nop.isa
rename : arch/sparc/isa/formats/priv.isa => src/arch/sparc/isa/formats/priv.isa
rename : arch/sparc/isa/formats/trap.isa => src/arch/sparc/isa/formats/trap.isa
rename : arch/sparc/isa/formats/unknown.isa => src/arch/sparc/isa/formats/unknown.isa
rename : arch/sparc/isa/includes.isa => src/arch/sparc/isa/includes.isa
rename : arch/sparc/isa/main.isa => src/arch/sparc/isa/main.isa
rename : arch/sparc/isa/operands.isa => src/arch/sparc/isa/operands.isa
rename : arch/sparc/isa_traits.hh => src/arch/sparc/isa_traits.hh
rename : arch/sparc/linux/linux.cc => src/arch/sparc/linux/linux.cc
rename : arch/sparc/linux/linux.hh => src/arch/sparc/linux/linux.hh
rename : arch/sparc/linux/process.cc => src/arch/sparc/linux/process.cc
rename : arch/sparc/linux/process.hh => src/arch/sparc/linux/process.hh
rename : arch/sparc/process.cc => src/arch/sparc/process.cc
rename : arch/sparc/process.hh => src/arch/sparc/process.hh
rename : arch/sparc/regfile.hh => src/arch/sparc/regfile.hh
rename : arch/sparc/solaris/process.cc => src/arch/sparc/solaris/process.cc
rename : arch/sparc/solaris/process.hh => src/arch/sparc/solaris/process.hh
rename : arch/sparc/solaris/solaris.cc => src/arch/sparc/solaris/solaris.cc
rename : arch/sparc/solaris/solaris.hh => src/arch/sparc/solaris/solaris.hh
rename : arch/sparc/stacktrace.hh => src/arch/sparc/stacktrace.hh
rename : arch/sparc/system.cc => src/arch/sparc/system.cc
rename : arch/sparc/system.hh => src/arch/sparc/system.hh
rename : arch/sparc/utility.hh => src/arch/sparc/utility.hh
rename : base/bitfield.hh => src/base/bitfield.hh
rename : base/callback.hh => src/base/callback.hh
rename : base/chunk_generator.hh => src/base/chunk_generator.hh
rename : base/circlebuf.cc => src/base/circlebuf.cc
rename : base/circlebuf.hh => src/base/circlebuf.hh
rename : base/compression/lzss_compression.cc => src/base/compression/lzss_compression.cc
rename : base/compression/lzss_compression.hh => src/base/compression/lzss_compression.hh
rename : base/compression/null_compression.hh => src/base/compression/null_compression.hh
rename : base/cprintf.cc => src/base/cprintf.cc
rename : base/cprintf.hh => src/base/cprintf.hh
rename : base/cprintf_formats.hh => src/base/cprintf_formats.hh
rename : base/crc.cc => src/base/crc.cc
rename : base/crc.hh => src/base/crc.hh
rename : base/date.cc => src/base/date.cc
rename : base/dbl_list.hh => src/base/dbl_list.hh
rename : base/endian.hh => src/base/endian.hh
rename : base/fast_alloc.cc => src/base/fast_alloc.cc
rename : base/fast_alloc.hh => src/base/fast_alloc.hh
rename : base/fenv.hh => src/base/fenv.hh
rename : base/fifo_buffer.cc => src/base/fifo_buffer.cc
rename : base/fifo_buffer.hh => src/base/fifo_buffer.hh
rename : base/hashmap.hh => src/base/hashmap.hh
rename : base/hostinfo.cc => src/base/hostinfo.cc
rename : base/hostinfo.hh => src/base/hostinfo.hh
rename : base/hybrid_pred.cc => src/base/hybrid_pred.cc
rename : base/hybrid_pred.hh => src/base/hybrid_pred.hh
rename : base/inet.cc => src/base/inet.cc
rename : base/inet.hh => src/base/inet.hh
rename : base/inifile.cc => src/base/inifile.cc
rename : base/inifile.hh => src/base/inifile.hh
rename : base/intmath.cc => src/base/intmath.cc
rename : base/intmath.hh => src/base/intmath.hh
rename : base/kgdb.h => src/base/kgdb.h
rename : base/loader/aout_object.cc => src/base/loader/aout_object.cc
rename : base/loader/aout_object.hh => src/base/loader/aout_object.hh
rename : base/loader/coff_sym.h => src/base/loader/coff_sym.h
rename : base/loader/coff_symconst.h => src/base/loader/coff_symconst.h
rename : base/loader/ecoff_object.cc => src/base/loader/ecoff_object.cc
rename : base/loader/ecoff_object.hh => src/base/loader/ecoff_object.hh
rename : base/loader/elf_object.cc => src/base/loader/elf_object.cc
rename : base/loader/elf_object.hh => src/base/loader/elf_object.hh
rename : base/loader/exec_aout.h => src/base/loader/exec_aout.h
rename : base/loader/exec_ecoff.h => src/base/loader/exec_ecoff.h
rename : base/loader/object_file.cc => src/base/loader/object_file.cc
rename : base/loader/object_file.hh => src/base/loader/object_file.hh
rename : base/loader/symtab.cc => src/base/loader/symtab.cc
rename : base/loader/symtab.hh => src/base/loader/symtab.hh
rename : base/match.cc => src/base/match.cc
rename : base/match.hh => src/base/match.hh
rename : base/misc.cc => src/base/misc.cc
rename : base/misc.hh => src/base/misc.hh
rename : base/mod_num.hh => src/base/mod_num.hh
rename : base/mysql.cc => src/base/mysql.cc
rename : base/mysql.hh => src/base/mysql.hh
rename : base/output.cc => src/base/output.cc
rename : base/output.hh => src/base/output.hh
rename : base/pollevent.cc => src/base/pollevent.cc
rename : base/pollevent.hh => src/base/pollevent.hh
rename : base/predictor.hh => src/base/predictor.hh
rename : base/random.cc => src/base/random.cc
rename : base/random.hh => src/base/random.hh
rename : base/range.cc => src/base/range.cc
rename : base/range.hh => src/base/range.hh
rename : base/refcnt.hh => src/base/refcnt.hh
rename : base/remote_gdb.cc => src/base/remote_gdb.cc
rename : base/remote_gdb.hh => src/base/remote_gdb.hh
rename : base/res_list.hh => src/base/res_list.hh
rename : base/sat_counter.cc => src/base/sat_counter.cc
rename : base/sat_counter.hh => src/base/sat_counter.hh
rename : base/sched_list.hh => src/base/sched_list.hh
rename : base/socket.cc => src/base/socket.cc
rename : base/socket.hh => src/base/socket.hh
rename : base/statistics.cc => src/base/statistics.cc
rename : base/statistics.hh => src/base/statistics.hh
rename : base/stats/events.cc => src/base/stats/events.cc
rename : base/stats/events.hh => src/base/stats/events.hh
rename : base/stats/flags.hh => src/base/stats/flags.hh
rename : base/stats/mysql.cc => src/base/stats/mysql.cc
rename : base/stats/mysql.hh => src/base/stats/mysql.hh
rename : base/stats/mysql_run.hh => src/base/stats/mysql_run.hh
rename : base/stats/output.hh => src/base/stats/output.hh
rename : base/stats/statdb.cc => src/base/stats/statdb.cc
rename : base/stats/statdb.hh => src/base/stats/statdb.hh
rename : base/stats/text.cc => src/base/stats/text.cc
rename : base/stats/text.hh => src/base/stats/text.hh
rename : base/stats/types.hh => src/base/stats/types.hh
rename : base/stats/visit.cc => src/base/stats/visit.cc
rename : base/stats/visit.hh => src/base/stats/visit.hh
rename : base/str.cc => src/base/str.cc
rename : base/str.hh => src/base/str.hh
rename : base/time.cc => src/base/time.cc
rename : base/time.hh => src/base/time.hh
rename : base/timebuf.hh => src/base/timebuf.hh
rename : base/trace.cc => src/base/trace.cc
rename : base/trace.hh => src/base/trace.hh
rename : base/traceflags.py => src/base/traceflags.py
rename : base/userinfo.cc => src/base/userinfo.cc
rename : base/userinfo.hh => src/base/userinfo.hh
rename : cpu/SConscript => src/cpu/SConscript
rename : cpu/base.cc => src/cpu/base.cc
rename : cpu/base.hh => src/cpu/base.hh
rename : cpu/base_dyn_inst.cc => src/cpu/base_dyn_inst.cc
rename : cpu/base_dyn_inst.hh => src/cpu/base_dyn_inst.hh
rename : cpu/cpu_exec_context.cc => src/cpu/cpu_exec_context.cc
rename : cpu/cpu_exec_context.hh => src/cpu/cpu_exec_context.hh
rename : cpu/cpu_models.py => src/cpu/cpu_models.py
rename : cpu/exec_context.hh => src/cpu/exec_context.hh
rename : cpu/exetrace.cc => src/cpu/exetrace.cc
rename : cpu/exetrace.hh => src/cpu/exetrace.hh
rename : cpu/inst_seq.hh => src/cpu/inst_seq.hh
rename : cpu/intr_control.cc => src/cpu/intr_control.cc
rename : cpu/intr_control.hh => src/cpu/intr_control.hh
rename : cpu/memtest/memtest.cc => src/cpu/memtest/memtest.cc
rename : cpu/memtest/memtest.hh => src/cpu/memtest/memtest.hh
rename : cpu/o3/2bit_local_pred.cc => src/cpu/o3/2bit_local_pred.cc
rename : cpu/o3/2bit_local_pred.hh => src/cpu/o3/2bit_local_pred.hh
rename : cpu/o3/alpha_cpu.cc => src/cpu/o3/alpha_cpu.cc
rename : cpu/o3/alpha_cpu.hh => src/cpu/o3/alpha_cpu.hh
rename : cpu/o3/alpha_cpu_builder.cc => src/cpu/o3/alpha_cpu_builder.cc
rename : cpu/o3/alpha_cpu_impl.hh => src/cpu/o3/alpha_cpu_impl.hh
rename : cpu/o3/alpha_dyn_inst.cc => src/cpu/o3/alpha_dyn_inst.cc
rename : cpu/o3/alpha_dyn_inst.hh => src/cpu/o3/alpha_dyn_inst.hh
rename : cpu/o3/alpha_dyn_inst_impl.hh => src/cpu/o3/alpha_dyn_inst_impl.hh
rename : cpu/o3/alpha_impl.hh => src/cpu/o3/alpha_impl.hh
rename : cpu/o3/alpha_params.hh => src/cpu/o3/alpha_params.hh
rename : cpu/o3/bpred_unit.cc => src/cpu/o3/bpred_unit.cc
rename : cpu/o3/bpred_unit.hh => src/cpu/o3/bpred_unit.hh
rename : cpu/o3/bpred_unit_impl.hh => src/cpu/o3/bpred_unit_impl.hh
rename : cpu/o3/btb.cc => src/cpu/o3/btb.cc
rename : cpu/o3/btb.hh => src/cpu/o3/btb.hh
rename : cpu/o3/comm.hh => src/cpu/o3/comm.hh
rename : cpu/o3/commit.cc => src/cpu/o3/commit.cc
rename : cpu/o3/commit.hh => src/cpu/o3/commit.hh
rename : cpu/o3/commit_impl.hh => src/cpu/o3/commit_impl.hh
rename : cpu/o3/cpu.cc => src/cpu/o3/cpu.cc
rename : cpu/o3/cpu.hh => src/cpu/o3/cpu.hh
rename : cpu/o3/cpu_policy.hh => src/cpu/o3/cpu_policy.hh
rename : cpu/o3/decode.cc => src/cpu/o3/decode.cc
rename : cpu/o3/decode.hh => src/cpu/o3/decode.hh
rename : cpu/o3/decode_impl.hh => src/cpu/o3/decode_impl.hh
rename : cpu/o3/fetch.cc => src/cpu/o3/fetch.cc
rename : cpu/o3/fetch.hh => src/cpu/o3/fetch.hh
rename : cpu/o3/fetch_impl.hh => src/cpu/o3/fetch_impl.hh
rename : cpu/o3/free_list.cc => src/cpu/o3/free_list.cc
rename : cpu/o3/free_list.hh => src/cpu/o3/free_list.hh
rename : cpu/o3/iew.cc => src/cpu/o3/iew.cc
rename : cpu/o3/iew.hh => src/cpu/o3/iew.hh
rename : cpu/o3/iew_impl.hh => src/cpu/o3/iew_impl.hh
rename : cpu/o3/inst_queue.cc => src/cpu/o3/inst_queue.cc
rename : cpu/o3/inst_queue.hh => src/cpu/o3/inst_queue.hh
rename : cpu/o3/inst_queue_impl.hh => src/cpu/o3/inst_queue_impl.hh
rename : cpu/o3/mem_dep_unit.cc => src/cpu/o3/mem_dep_unit.cc
rename : cpu/o3/mem_dep_unit.hh => src/cpu/o3/mem_dep_unit.hh
rename : cpu/o3/mem_dep_unit_impl.hh => src/cpu/o3/mem_dep_unit_impl.hh
rename : cpu/o3/ras.cc => src/cpu/o3/ras.cc
rename : cpu/o3/ras.hh => src/cpu/o3/ras.hh
rename : cpu/o3/regfile.hh => src/cpu/o3/regfile.hh
rename : cpu/o3/rename.cc => src/cpu/o3/rename.cc
rename : cpu/o3/rename.hh => src/cpu/o3/rename.hh
rename : cpu/o3/rename_impl.hh => src/cpu/o3/rename_impl.hh
rename : cpu/o3/rename_map.cc => src/cpu/o3/rename_map.cc
rename : cpu/o3/rename_map.hh => src/cpu/o3/rename_map.hh
rename : cpu/o3/rob.cc => src/cpu/o3/rob.cc
rename : cpu/o3/rob.hh => src/cpu/o3/rob.hh
rename : cpu/o3/rob_impl.hh => src/cpu/o3/rob_impl.hh
rename : cpu/o3/sat_counter.cc => src/cpu/o3/sat_counter.cc
rename : cpu/o3/sat_counter.hh => src/cpu/o3/sat_counter.hh
rename : cpu/o3/store_set.cc => src/cpu/o3/store_set.cc
rename : cpu/o3/store_set.hh => src/cpu/o3/store_set.hh
rename : cpu/o3/tournament_pred.cc => src/cpu/o3/tournament_pred.cc
rename : cpu/o3/tournament_pred.hh => src/cpu/o3/tournament_pred.hh
rename : cpu/op_class.cc => src/cpu/op_class.cc
rename : cpu/op_class.hh => src/cpu/op_class.hh
rename : cpu/ozone/cpu.cc => src/cpu/ozone/cpu.cc
rename : cpu/ozone/cpu.hh => src/cpu/ozone/cpu.hh
rename : cpu/ozone/cpu_impl.hh => src/cpu/ozone/cpu_impl.hh
rename : cpu/ozone/ea_list.cc => src/cpu/ozone/ea_list.cc
rename : cpu/ozone/ea_list.hh => src/cpu/ozone/ea_list.hh
rename : cpu/pc_event.cc => src/cpu/pc_event.cc
rename : cpu/pc_event.hh => src/cpu/pc_event.hh
rename : cpu/profile.cc => src/cpu/profile.cc
rename : cpu/profile.hh => src/cpu/profile.hh
rename : cpu/simple/atomic.cc => src/cpu/simple/atomic.cc
rename : cpu/simple/atomic.hh => src/cpu/simple/atomic.hh
rename : cpu/simple/base.cc => src/cpu/simple/base.cc
rename : cpu/simple/base.hh => src/cpu/simple/base.hh
rename : cpu/simple/timing.cc => src/cpu/simple/timing.cc
rename : cpu/simple/timing.hh => src/cpu/simple/timing.hh
rename : cpu/smt.hh => src/cpu/smt.hh
rename : cpu/static_inst.cc => src/cpu/static_inst.cc
rename : cpu/static_inst.hh => src/cpu/static_inst.hh
rename : cpu/trace/opt_cpu.cc => src/cpu/trace/opt_cpu.cc
rename : cpu/trace/opt_cpu.hh => src/cpu/trace/opt_cpu.hh
rename : cpu/trace/reader/ibm_reader.cc => src/cpu/trace/reader/ibm_reader.cc
rename : cpu/trace/reader/ibm_reader.hh => src/cpu/trace/reader/ibm_reader.hh
rename : cpu/trace/reader/itx_reader.cc => src/cpu/trace/reader/itx_reader.cc
rename : cpu/trace/reader/itx_reader.hh => src/cpu/trace/reader/itx_reader.hh
rename : cpu/trace/reader/m5_reader.cc => src/cpu/trace/reader/m5_reader.cc
rename : cpu/trace/reader/m5_reader.hh => src/cpu/trace/reader/m5_reader.hh
rename : cpu/trace/reader/mem_trace_reader.cc => src/cpu/trace/reader/mem_trace_reader.cc
rename : cpu/trace/reader/mem_trace_reader.hh => src/cpu/trace/reader/mem_trace_reader.hh
rename : cpu/trace/trace_cpu.cc => src/cpu/trace/trace_cpu.cc
rename : cpu/trace/trace_cpu.hh => src/cpu/trace/trace_cpu.hh
rename : dev/alpha_access.h => src/dev/alpha_access.h
rename : dev/alpha_console.cc => src/dev/alpha_console.cc
rename : dev/alpha_console.hh => src/dev/alpha_console.hh
rename : dev/baddev.cc => src/dev/baddev.cc
rename : dev/baddev.hh => src/dev/baddev.hh
rename : dev/disk_image.cc => src/dev/disk_image.cc
rename : dev/disk_image.hh => src/dev/disk_image.hh
rename : dev/etherbus.cc => src/dev/etherbus.cc
rename : dev/etherbus.hh => src/dev/etherbus.hh
rename : dev/etherdump.cc => src/dev/etherdump.cc
rename : dev/etherdump.hh => src/dev/etherdump.hh
rename : dev/etherint.cc => src/dev/etherint.cc
rename : dev/etherint.hh => src/dev/etherint.hh
rename : dev/etherlink.cc => src/dev/etherlink.cc
rename : dev/etherlink.hh => src/dev/etherlink.hh
rename : dev/etherpkt.cc => src/dev/etherpkt.cc
rename : dev/etherpkt.hh => src/dev/etherpkt.hh
rename : dev/ethertap.cc => src/dev/ethertap.cc
rename : dev/ethertap.hh => src/dev/ethertap.hh
rename : dev/ide_atareg.h => src/dev/ide_atareg.h
rename : dev/ide_ctrl.cc => src/dev/ide_ctrl.cc
rename : dev/ide_ctrl.hh => src/dev/ide_ctrl.hh
rename : dev/ide_disk.cc => src/dev/ide_disk.cc
rename : dev/ide_disk.hh => src/dev/ide_disk.hh
rename : dev/ide_wdcreg.h => src/dev/ide_wdcreg.h
rename : dev/io_device.cc => src/dev/io_device.cc
rename : dev/io_device.hh => src/dev/io_device.hh
rename : dev/isa_fake.cc => src/dev/isa_fake.cc
rename : dev/isa_fake.hh => src/dev/isa_fake.hh
rename : dev/ns_gige.cc => src/dev/ns_gige.cc
rename : dev/ns_gige.hh => src/dev/ns_gige.hh
rename : dev/ns_gige_reg.h => src/dev/ns_gige_reg.h
rename : dev/pciconfigall.cc => src/dev/pciconfigall.cc
rename : dev/pciconfigall.hh => src/dev/pciconfigall.hh
rename : dev/pcidev.cc => src/dev/pcidev.cc
rename : dev/pcidev.hh => src/dev/pcidev.hh
rename : dev/pcireg.h => src/dev/pcireg.h
rename : dev/pitreg.h => src/dev/pitreg.h
rename : dev/pktfifo.cc => src/dev/pktfifo.cc
rename : dev/pktfifo.hh => src/dev/pktfifo.hh
rename : dev/platform.cc => src/dev/platform.cc
rename : dev/platform.hh => src/dev/platform.hh
rename : dev/rtcreg.h => src/dev/rtcreg.h
rename : dev/simconsole.cc => src/dev/simconsole.cc
rename : dev/simconsole.hh => src/dev/simconsole.hh
rename : dev/simple_disk.cc => src/dev/simple_disk.cc
rename : dev/simple_disk.hh => src/dev/simple_disk.hh
rename : dev/sinic.cc => src/dev/sinic.cc
rename : dev/sinic.hh => src/dev/sinic.hh
rename : dev/sinicreg.hh => src/dev/sinicreg.hh
rename : dev/tsunami.cc => src/dev/tsunami.cc
rename : dev/tsunami.hh => src/dev/tsunami.hh
rename : dev/tsunami_cchip.cc => src/dev/tsunami_cchip.cc
rename : dev/tsunami_cchip.hh => src/dev/tsunami_cchip.hh
rename : dev/tsunami_io.cc => src/dev/tsunami_io.cc
rename : dev/tsunami_io.hh => src/dev/tsunami_io.hh
rename : dev/tsunami_pchip.cc => src/dev/tsunami_pchip.cc
rename : dev/tsunami_pchip.hh => src/dev/tsunami_pchip.hh
rename : dev/tsunamireg.h => src/dev/tsunamireg.h
rename : dev/uart.cc => src/dev/uart.cc
rename : dev/uart.hh => src/dev/uart.hh
rename : dev/uart8250.cc => src/dev/uart8250.cc
rename : dev/uart8250.hh => src/dev/uart8250.hh
rename : kern/kernel_stats.cc => src/kern/kernel_stats.cc
rename : kern/kernel_stats.hh => src/kern/kernel_stats.hh
rename : kern/linux/events.cc => src/kern/linux/events.cc
rename : kern/linux/events.hh => src/kern/linux/events.hh
rename : kern/linux/linux.hh => src/kern/linux/linux.hh
rename : kern/linux/linux_syscalls.cc => src/kern/linux/linux_syscalls.cc
rename : kern/linux/linux_syscalls.hh => src/kern/linux/linux_syscalls.hh
rename : kern/linux/printk.cc => src/kern/linux/printk.cc
rename : kern/linux/printk.hh => src/kern/linux/printk.hh
rename : kern/linux/sched.hh => src/kern/linux/sched.hh
rename : kern/solaris/solaris.hh => src/kern/solaris/solaris.hh
rename : kern/system_events.cc => src/kern/system_events.cc
rename : kern/system_events.hh => src/kern/system_events.hh
rename : kern/tru64/dump_mbuf.cc => src/kern/tru64/dump_mbuf.cc
rename : kern/tru64/dump_mbuf.hh => src/kern/tru64/dump_mbuf.hh
rename : kern/tru64/mbuf.hh => src/kern/tru64/mbuf.hh
rename : kern/tru64/printf.cc => src/kern/tru64/printf.cc
rename : kern/tru64/printf.hh => src/kern/tru64/printf.hh
rename : kern/tru64/tru64.hh => src/kern/tru64/tru64.hh
rename : kern/tru64/tru64_events.cc => src/kern/tru64/tru64_events.cc
rename : kern/tru64/tru64_events.hh => src/kern/tru64/tru64_events.hh
rename : kern/tru64/tru64_syscalls.cc => src/kern/tru64/tru64_syscalls.cc
rename : kern/tru64/tru64_syscalls.hh => src/kern/tru64/tru64_syscalls.hh
rename : mem/bridge.cc => src/mem/bridge.cc
rename : mem/bridge.hh => src/mem/bridge.hh
rename : mem/bus.cc => src/mem/bus.cc
rename : mem/bus.hh => src/mem/bus.hh
rename : mem/cache/prefetch/tagged_prefetcher_impl.hh => src/mem/cache/prefetch/tagged_prefetcher_impl.hh
rename : mem/config/prefetch.hh => src/mem/config/prefetch.hh
rename : mem/mem_object.cc => src/mem/mem_object.cc
rename : mem/mem_object.hh => src/mem/mem_object.hh
rename : mem/packet.cc => src/mem/packet.cc
rename : mem/packet.hh => src/mem/packet.hh
rename : mem/page_table.cc => src/mem/page_table.cc
rename : mem/page_table.hh => src/mem/page_table.hh
rename : mem/physical.cc => src/mem/physical.cc
rename : mem/physical.hh => src/mem/physical.hh
rename : mem/port.cc => src/mem/port.cc
rename : mem/port.hh => src/mem/port.hh
rename : mem/request.hh => src/mem/request.hh
rename : mem/translating_port.cc => src/mem/translating_port.cc
rename : mem/translating_port.hh => src/mem/translating_port.hh
rename : mem/vport.cc => src/mem/vport.cc
rename : mem/vport.hh => src/mem/vport.hh
rename : python/SConscript => src/python/SConscript
rename : python/m5/__init__.py => src/python/m5/__init__.py
rename : python/m5/config.py => src/python/m5/config.py
rename : python/m5/convert.py => src/python/m5/convert.py
rename : python/m5/multidict.py => src/python/m5/multidict.py
rename : python/m5/objects/AlphaConsole.py => src/python/m5/objects/AlphaConsole.py
rename : python/m5/objects/AlphaFullCPU.py => src/python/m5/objects/AlphaFullCPU.py
rename : python/m5/objects/AlphaTLB.py => src/python/m5/objects/AlphaTLB.py
rename : python/m5/objects/BadDevice.py => src/python/m5/objects/BadDevice.py
rename : python/m5/objects/BaseCPU.py => src/python/m5/objects/BaseCPU.py
rename : python/m5/objects/BaseCache.py => src/python/m5/objects/BaseCache.py
rename : python/m5/objects/Bridge.py => src/python/m5/objects/Bridge.py
rename : python/m5/objects/Bus.py => src/python/m5/objects/Bus.py
rename : python/m5/objects/CoherenceProtocol.py => src/python/m5/objects/CoherenceProtocol.py
rename : python/m5/objects/Device.py => src/python/m5/objects/Device.py
rename : python/m5/objects/DiskImage.py => src/python/m5/objects/DiskImage.py
rename : python/m5/objects/Ethernet.py => src/python/m5/objects/Ethernet.py
rename : python/m5/objects/Ide.py => src/python/m5/objects/Ide.py
rename : python/m5/objects/IntrControl.py => src/python/m5/objects/IntrControl.py
rename : python/m5/objects/MemObject.py => src/python/m5/objects/MemObject.py
rename : python/m5/objects/MemTest.py => src/python/m5/objects/MemTest.py
rename : python/m5/objects/Pci.py => src/python/m5/objects/Pci.py
rename : python/m5/objects/PhysicalMemory.py => src/python/m5/objects/PhysicalMemory.py
rename : python/m5/objects/Platform.py => src/python/m5/objects/Platform.py
rename : python/m5/objects/Process.py => src/python/m5/objects/Process.py
rename : python/m5/objects/Repl.py => src/python/m5/objects/Repl.py
rename : python/m5/objects/Root.py => src/python/m5/objects/Root.py
rename : python/m5/objects/SimConsole.py => src/python/m5/objects/SimConsole.py
rename : python/m5/objects/SimpleDisk.py => src/python/m5/objects/SimpleDisk.py
rename : python/m5/objects/System.py => src/python/m5/objects/System.py
rename : python/m5/objects/Tsunami.py => src/python/m5/objects/Tsunami.py
rename : python/m5/objects/Uart.py => src/python/m5/objects/Uart.py
rename : python/m5/smartdict.py => src/python/m5/smartdict.py
rename : sim/async.hh => src/sim/async.hh
rename : sim/builder.cc => src/sim/builder.cc
rename : sim/builder.hh => src/sim/builder.hh
rename : sim/byteswap.hh => src/sim/byteswap.hh
rename : sim/debug.cc => src/sim/debug.cc
rename : sim/debug.hh => src/sim/debug.hh
rename : sim/eventq.cc => src/sim/eventq.cc
rename : sim/eventq.hh => src/sim/eventq.hh
rename : sim/faults.cc => src/sim/faults.cc
rename : sim/faults.hh => src/sim/faults.hh
rename : sim/host.hh => src/sim/host.hh
rename : sim/main.cc => src/sim/main.cc
rename : sim/param.cc => src/sim/param.cc
rename : sim/param.hh => src/sim/param.hh
rename : sim/process.cc => src/sim/process.cc
rename : sim/process.hh => src/sim/process.hh
rename : sim/pseudo_inst.cc => src/sim/pseudo_inst.cc
rename : sim/pseudo_inst.hh => src/sim/pseudo_inst.hh
rename : sim/root.cc => src/sim/root.cc
rename : sim/serialize.cc => src/sim/serialize.cc
rename : sim/serialize.hh => src/sim/serialize.hh
rename : sim/sim_events.cc => src/sim/sim_events.cc
rename : sim/sim_events.hh => src/sim/sim_events.hh
rename : sim/sim_exit.hh => src/sim/sim_exit.hh
rename : sim/sim_object.cc => src/sim/sim_object.cc
rename : sim/sim_object.hh => src/sim/sim_object.hh
rename : sim/startup.cc => src/sim/startup.cc
rename : sim/startup.hh => src/sim/startup.hh
rename : sim/stat_control.cc => src/sim/stat_control.cc
rename : sim/stat_control.hh => src/sim/stat_control.hh
rename : sim/stats.hh => src/sim/stats.hh
rename : sim/syscall_emul.cc => src/sim/syscall_emul.cc
rename : sim/syscall_emul.hh => src/sim/syscall_emul.hh
rename : sim/system.cc => src/sim/system.cc
rename : sim/system.hh => src/sim/system.hh
rename : sim/vptr.hh => src/sim/vptr.hh
rename : test/Makefile => src/unittest/Makefile
rename : test/bitvectest.cc => src/unittest/bitvectest.cc
rename : test/circletest.cc => src/unittest/circletest.cc
rename : test/cprintftest.cc => src/unittest/cprintftest.cc
rename : test/foo.ini => src/unittest/foo.ini
rename : test/genini.py => src/unittest/genini.py
rename : test/initest.cc => src/unittest/initest.cc
rename : test/initest.ini => src/unittest/initest.ini
rename : test/lru_test.cc => src/unittest/lru_test.cc
rename : test/nmtest.cc => src/unittest/nmtest.cc
rename : test/offtest.cc => src/unittest/offtest.cc
rename : test/paramtest.cc => src/unittest/paramtest.cc
rename : test/rangetest.cc => src/unittest/rangetest.cc
rename : test/sized_test.cc => src/unittest/sized_test.cc
rename : test/stattest.cc => src/unittest/stattest.cc
rename : test/strnumtest.cc => src/unittest/strnumtest.cc
rename : test/symtest.cc => src/unittest/symtest.cc
rename : test/tokentest.cc => src/unittest/tokentest.cc
rename : test/tracetest.cc => src/unittest/tracetest.cc
extra : convert_revision : cab6a5271ca1b368193cd948e5d3dcc47ab1bd48
This commit is contained in:
158
ext/ply/CHANGES
Normal file
158
ext/ply/CHANGES
Normal file
@@ -0,0 +1,158 @@
|
||||
Version 1.3
|
||||
------------------------------
|
||||
12/10/02: jmdyck
|
||||
Various minor adjustments to the code that Dave checked in today.
|
||||
Updated test/yacc_{inf,unused}.exp to reflect today's changes.
|
||||
|
||||
12/10/02: beazley
|
||||
Incorporated a variety of minor bug fixes to empty production
|
||||
handling and infinite recursion checking. Contributed by
|
||||
Michael Dyck.
|
||||
|
||||
12/10/02: beazley
|
||||
Removed bogus recover() method call in yacc.restart()
|
||||
|
||||
Version 1.2
|
||||
------------------------------
|
||||
11/27/02: beazley
|
||||
Lexer and parser objects are now available as an attribute
|
||||
of tokens and slices respectively. For example:
|
||||
|
||||
def t_NUMBER(t):
|
||||
r'\d+'
|
||||
print t.lexer
|
||||
|
||||
def p_expr_plus(t):
|
||||
'expr: expr PLUS expr'
|
||||
print t.lexer
|
||||
print t.parser
|
||||
|
||||
This can be used for state management (if needed).
|
||||
|
||||
10/31/02: beazley
|
||||
Modified yacc.py to work with Python optimize mode. To make
|
||||
this work, you need to use
|
||||
|
||||
yacc.yacc(optimize=1)
|
||||
|
||||
Furthermore, you need to first run Python in normal mode
|
||||
to generate the necessary parsetab.py files. After that,
|
||||
you can use python -O or python -OO.
|
||||
|
||||
Note: optimized mode turns off a lot of error checking.
|
||||
Only use when you are sure that your grammar is working.
|
||||
Make sure parsetab.py is up to date!
|
||||
|
||||
10/30/02: beazley
|
||||
Added cloning of Lexer objects. For example:
|
||||
|
||||
import copy
|
||||
l = lex.lex()
|
||||
lc = copy.copy(l)
|
||||
|
||||
l.input("Some text")
|
||||
lc.input("Some other text")
|
||||
...
|
||||
|
||||
This might be useful if the same "lexer" is meant to
|
||||
be used in different contexts---or if multiple lexers
|
||||
are running concurrently.
|
||||
|
||||
10/30/02: beazley
|
||||
Fixed subtle bug with first set computation and empty productions.
|
||||
Patch submitted by Michael Dyck.
|
||||
|
||||
10/30/02: beazley
|
||||
Fixed error messages to use "filename:line: message" instead
|
||||
of "filename:line. message". This makes error reporting more
|
||||
friendly to emacs. Patch submitted by François Pinard.
|
||||
|
||||
10/30/02: beazley
|
||||
Improvements to parser.out file. Terminals and nonterminals
|
||||
are sorted instead of being printed in random order.
|
||||
Patch submitted by François Pinard.
|
||||
|
||||
10/30/02: beazley
|
||||
Improvements to parser.out file output. Rules are now printed
|
||||
in a way that's easier to understand. Contributed by Russ Cox.
|
||||
|
||||
10/30/02: beazley
|
||||
Added 'nonassoc' associativity support. This can be used
|
||||
to disable the chaining of operators like a < b < c.
|
||||
To use, simply specify 'nonassoc' in the precedence table
|
||||
|
||||
precedence = (
|
||||
('nonassoc', 'LESSTHAN', 'GREATERTHAN'), # Nonassociative operators
|
||||
('left', 'PLUS', 'MINUS'),
|
||||
('left', 'TIMES', 'DIVIDE'),
|
||||
('right', 'UMINUS'), # Unary minus operator
|
||||
)
|
||||
|
||||
Patch contributed by Russ Cox.
|
||||
|
||||
10/30/02: beazley
|
||||
Modified the lexer to provide optional support for Python -O and -OO
|
||||
modes. To make this work, Python *first* needs to be run in
|
||||
unoptimized mode. This reads the lexing information and creates a
|
||||
file "lextab.py". Then, run lex like this:
|
||||
|
||||
# module foo.py
|
||||
...
|
||||
...
|
||||
lex.lex(optimize=1)
|
||||
|
||||
Once the lextab file has been created, subsequent calls to
|
||||
lex.lex() will read data from the lextab file instead of using
|
||||
introspection. In optimized mode (-O, -OO) everything should
|
||||
work normally despite the loss of doc strings.
|
||||
|
||||
To change the name of the file 'lextab.py' use the following:
|
||||
|
||||
lex.lex(lextab="footab")
|
||||
|
||||
(this creates a file footab.py)
|
||||
|
||||
|
||||
Version 1.1 October 25, 2001
|
||||
------------------------------
|
||||
|
||||
10/25/01: beazley
|
||||
Modified the table generator to produce much more compact data.
|
||||
This should greatly reduce the size of the parsetab.py[c] file.
|
||||
Caveat: the tables still need to be constructed so a little more
|
||||
work is done in parsetab on import.
|
||||
|
||||
10/25/01: beazley
|
||||
There may be a possible bug in the cycle detector that reports errors
|
||||
about infinite recursion. I'm having a little trouble tracking it
|
||||
down, but if you get this problem, you can disable the cycle
|
||||
detector as follows:
|
||||
|
||||
yacc.yacc(check_recursion = 0)
|
||||
|
||||
10/25/01: beazley
|
||||
Fixed a bug in lex.py that sometimes caused illegal characters to be
|
||||
reported incorrectly. Reported by Sverre Jørgensen.
|
||||
|
||||
7/8/01 : beazley
|
||||
Added a reference to the underlying lexer object when tokens are handled by
|
||||
functions. The lexer is available as the 'lexer' attribute. This
|
||||
was added to provide better lexing support for languages such as Fortran
|
||||
where certain types of tokens can't be conveniently expressed as regular
|
||||
expressions (and where the tokenizing function may want to perform a
|
||||
little backtracking). Suggested by Pearu Peterson.
|
||||
|
||||
6/20/01 : beazley
|
||||
Modified yacc() function so that an optional starting symbol can be specified.
|
||||
For example:
|
||||
|
||||
yacc.yacc(start="statement")
|
||||
|
||||
Normally yacc always treats the first production rule as the starting symbol.
|
||||
However, if you are debugging your grammar it may be useful to specify
|
||||
an alternative starting symbol. Idea suggested by Rich Salz.
|
||||
|
||||
Version 1.0 June 18, 2001
|
||||
--------------------------
|
||||
Initial public offering
|
||||
|
||||
504
ext/ply/COPYING
Normal file
504
ext/ply/COPYING
Normal file
@@ -0,0 +1,504 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
||||
249
ext/ply/README
Normal file
249
ext/ply/README
Normal file
@@ -0,0 +1,249 @@
|
||||
PLY (Python Lex-Yacc) Version 1.2 (November 27, 2002)
|
||||
|
||||
David M. Beazley
|
||||
Department of Computer Science
|
||||
University of Chicago
|
||||
Chicago, IL 60637
|
||||
beazley@cs.uchicago.edu
|
||||
|
||||
Copyright (C) 2001 David M. Beazley
|
||||
|
||||
$Header: /home/stever/bk/newmem2/ext/ply/README 1.1 03/06/06 14:53:34-00:00 stever@ $
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
See the file COPYING for a complete copy of the LGPL.
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
PLY is a 100% Python implementation of the common parsing tools lex
|
||||
and yacc. Although several other parsing tools are available for
|
||||
Python, there are several reasons why you might want to consider PLY:
|
||||
|
||||
- The tools are very closely modeled after traditional lex/yacc.
|
||||
If you know how to use these tools in C, you will find PLY
|
||||
to be similar.
|
||||
|
||||
- PLY provides *very* extensive error reporting and diagnostic
|
||||
information to assist in parser construction. The original
|
||||
implementation was developed for instructional purposes. As
|
||||
a result, the system tries to identify the most common types
|
||||
of errors made by novice users.
|
||||
|
||||
- PLY provides full support for empty productions, error recovery,
|
||||
precedence specifiers, and moderately ambiguous grammars.
|
||||
|
||||
- Parsing is based on LR-parsing which is fast, memory efficient,
|
||||
better suited to large grammars, and which has a number of nice
|
||||
properties when dealing with syntax errors and other parsing problems.
|
||||
Currently, PLY builds its parsing tables using the SLR algorithm which
|
||||
is slightly weaker than LALR(1) used in traditional yacc.
|
||||
|
||||
- Like John Aycock's excellent SPARK toolkit, PLY uses Python
|
||||
reflection to build lexers and parsers. This greatly simplifies
|
||||
the task of parser construction since it reduces the number of files
|
||||
and eliminates the need to run a separate lex/yacc tool before
|
||||
running your program.
|
||||
|
||||
- PLY can be used to build parsers for "real" programming languages.
|
||||
Although it is not ultra-fast due to its Python implementation,
|
||||
PLY can be used to parse grammars consisting of several hundred
|
||||
rules (as might be found for a language like C). The lexer and LR
|
||||
parser are also reasonably efficient when parsing typically
|
||||
sized programs.
|
||||
|
||||
The original version of PLY was developed for an Introduction to
|
||||
Compilers course where students used it to build a compiler for a
|
||||
simple Pascal-like language. Their compiler had to include lexical
|
||||
analysis, parsing, type checking, type inference, and generation of
|
||||
assembly code for the SPARC processor. Because of this, the current
|
||||
implementation has been extensively tested and debugged. In addition,
|
||||
most of the API and error checking steps have been adapted to address
|
||||
common usability problems.
|
||||
|
||||
How to Use
|
||||
==========
|
||||
|
||||
PLY consists of two files : lex.py and yacc.py. To use the system,
|
||||
simply copy these files to your project and import them like standard
|
||||
Python modules.
|
||||
|
||||
The file doc/ply.html contains complete documentation on how to use
|
||||
the system.
|
||||
|
||||
The example directory contains several different examples including a
|
||||
PLY specification for ANSI C as given in K&R 2nd Ed. Note: To use
|
||||
the examples, you will need to copy the lex.py and yacc.py files to
|
||||
the example directory.
|
||||
|
||||
A simple example is found at the end of this document
|
||||
|
||||
Requirements
|
||||
============
|
||||
PLY requires the use of Python 2.0 or greater. It should work on
|
||||
just about any platform.
|
||||
|
||||
Resources
|
||||
=========
|
||||
|
||||
More information about PLY can be obtained on the PLY webpage at:
|
||||
|
||||
http://systems.cs.uchicago.edu/ply
|
||||
|
||||
For a detailed overview of parsing theory, consult the excellent
|
||||
book "Compilers : Principles, Techniques, and Tools" by Aho, Sethi, and
|
||||
Ullman. The topics found in "Lex & Yacc" by Levine, Mason, and Brown
|
||||
may also be useful.
|
||||
|
||||
Given that this is the first release, I welcome your comments on how
|
||||
to improve the current implementation. See the TODO file for things that
|
||||
still need to be done.
|
||||
|
||||
Acknowledgments
|
||||
===============
|
||||
|
||||
A special thanks is in order for all of the students in CS326 who
|
||||
suffered through about 25 different versions of these tools :-).
|
||||
|
||||
Example
|
||||
=======
|
||||
|
||||
Here is a simple example showing a PLY implementation of a calculator with variables.
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# calc.py
|
||||
#
|
||||
# A simple calculator with variables.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
tokens = (
|
||||
'NAME','NUMBER',
|
||||
'PLUS','MINUS','TIMES','DIVIDE','EQUALS',
|
||||
'LPAREN','RPAREN',
|
||||
)
|
||||
|
||||
# Tokens
|
||||
|
||||
t_PLUS = r'\+'
|
||||
t_MINUS = r'-'
|
||||
t_TIMES = r'\*'
|
||||
t_DIVIDE = r'/'
|
||||
t_EQUALS = r'='
|
||||
t_LPAREN = r'\('
|
||||
t_RPAREN = r'\)'
|
||||
t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
|
||||
|
||||
def t_NUMBER(t):
|
||||
r'\d+'
|
||||
try:
|
||||
t.value = int(t.value)
|
||||
except ValueError:
|
||||
print "Integer value too large", t.value
|
||||
t.value = 0
|
||||
return t
|
||||
|
||||
# Ignored characters
|
||||
t_ignore = " \t"
|
||||
|
||||
def t_newline(t):
|
||||
r'\n+'
|
||||
t.lineno += t.value.count("\n")
|
||||
|
||||
def t_error(t):
|
||||
print "Illegal character '%s'" % t.value[0]
|
||||
t.skip(1)
|
||||
|
||||
# Build the lexer
|
||||
import lex
|
||||
lex.lex()
|
||||
|
||||
# Precedence rules for the arithmetic operators
|
||||
precedence = (
|
||||
('left','PLUS','MINUS'),
|
||||
('left','TIMES','DIVIDE'),
|
||||
('right','UMINUS'),
|
||||
)
|
||||
|
||||
# dictionary of names (for storing variables)
|
||||
names = { }
|
||||
|
||||
def p_statement_assign(t):
|
||||
'statement : NAME EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement_expr(t):
|
||||
'statement : expression'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[2] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
def p_error(t):
|
||||
print "Syntax error at '%s'" % t.value
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
while 1:
|
||||
try:
|
||||
s = raw_input('calc > ')
|
||||
except EOFError:
|
||||
break
|
||||
yacc.parse(s)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
22
ext/ply/TODO
Normal file
22
ext/ply/TODO
Normal file
@@ -0,0 +1,22 @@
|
||||
The PLY to-do list:
|
||||
|
||||
$Header: /home/stever/bk/newmem2/ext/ply/TODO 1.1 03/06/06 14:53:34-00:00 stever@ $
|
||||
|
||||
1. Create a Python package using distutils
|
||||
|
||||
2. More interesting parsing examples.
|
||||
|
||||
3. Work on the ANSI C grammar so that it can actually parse C programs. To do this,
|
||||
some extra code needs to be added to the lexer to deal with typedef names and enumeration
|
||||
constants.
|
||||
|
||||
4. Get LALR(1) to work. Hard, but not impossible.
|
||||
|
||||
5. More tests in the test directory.
|
||||
|
||||
6. Performance improvements and cleanup in yacc.py.
|
||||
|
||||
7. More documentation.
|
||||
|
||||
8. Lots and lots of cleanup.
|
||||
|
||||
1642
ext/ply/doc/ply.html
Normal file
1642
ext/ply/doc/ply.html
Normal file
File diff suppressed because it is too large
Load Diff
2
ext/ply/example/ansic/README
Normal file
2
ext/ply/example/ansic/README
Normal file
@@ -0,0 +1,2 @@
|
||||
This example is incomplete. Was going to specify an ANSI C parser.
|
||||
This is part of it.
|
||||
161
ext/ply/example/ansic/clex.py
Normal file
161
ext/ply/example/ansic/clex.py
Normal file
@@ -0,0 +1,161 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# clex.py
|
||||
#
|
||||
# A lexer for ANSI C.
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
import lex
|
||||
|
||||
# Reserved words
|
||||
reserved = (
|
||||
'AUTO', 'BREAK', 'CASE', 'CHAR', 'CONST', 'CONTINUE', 'DEFAULT', 'DO', 'DOUBLE',
|
||||
'ELSE', 'ENUM', 'EXTERN', 'FLOAT', 'FOR', 'GOTO', 'IF', 'INT', 'LONG', 'REGISTER',
|
||||
'RETURN', 'SHORT', 'SIGNED', 'SIZEOF', 'STATIC', 'STRUCT', 'SWITCH', 'TYPEDEF',
|
||||
'UNION', 'UNSIGNED', 'VOID', 'VOLATILE', 'WHILE',
|
||||
)
|
||||
|
||||
tokens = reserved + (
|
||||
# Literals (identifier, integer constant, float constant, string constant, char const)
|
||||
'ID', 'TYPEID', 'ICONST', 'FCONST', 'SCONST', 'CCONST',
|
||||
|
||||
# Operators (+,-,*,/,%,|,&,~,^,<<,>>, ||, &&, !, <, <=, >, >=, ==, !=)
|
||||
'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'MOD',
|
||||
'OR', 'AND', 'NOT', 'XOR', 'LSHIFT', 'RSHIFT',
|
||||
'LOR', 'LAND', 'LNOT',
|
||||
'LT', 'LE', 'GT', 'GE', 'EQ', 'NE',
|
||||
|
||||
# Assignment (=, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=)
|
||||
'EQUALS', 'TIMESEQUAL', 'DIVEQUAL', 'MODEQUAL', 'PLUSEQUAL', 'MINUSEQUAL',
|
||||
'LSHIFTEQUAL','RSHIFTEQUAL', 'ANDEQUAL', 'XOREQUAL', 'OREQUAL',
|
||||
|
||||
# Increment/decrement (++,--)
|
||||
'PLUSPLUS', 'MINUSMINUS',
|
||||
|
||||
# Structure dereference (->)
|
||||
'ARROW',
|
||||
|
||||
# Conditional operator (?)
|
||||
'CONDOP',
|
||||
|
||||
# Delimeters ( ) [ ] { } , . ; :
|
||||
'LPAREN', 'RPAREN',
|
||||
'LBRACKET', 'RBRACKET',
|
||||
'LBRACE', 'RBRACE',
|
||||
'COMMA', 'PERIOD', 'SEMI', 'COLON',
|
||||
|
||||
# Ellipsis (...)
|
||||
'ELLIPSIS',
|
||||
)
|
||||
|
||||
# Completely ignored characters
|
||||
t_ignore = ' \t\x0c'
|
||||
|
||||
# Newlines
|
||||
def t_NEWLINE(t):
|
||||
r'\n+'
|
||||
t.lineno += t.value.count("\n")
|
||||
|
||||
# Operators
|
||||
t_PLUS = r'\+'
|
||||
t_MINUS = r'-'
|
||||
t_TIMES = r'\*'
|
||||
t_DIVIDE = r'/'
|
||||
t_MOD = r'%'
|
||||
t_OR = r'\|'
|
||||
t_AND = r'&'
|
||||
t_NOT = r'~'
|
||||
t_XOR = r'^'
|
||||
t_LSHIFT = r'<<'
|
||||
t_RSHIFT = r'>>'
|
||||
t_LOR = r'\|\|'
|
||||
t_LAND = r'&&'
|
||||
t_LNOT = r'!'
|
||||
t_LT = r'<'
|
||||
t_GT = r'>'
|
||||
t_LE = r'<='
|
||||
t_GE = r'>='
|
||||
t_EQ = r'=='
|
||||
t_NE = r'!='
|
||||
|
||||
# Assignment operators
|
||||
|
||||
t_EQUALS = r'='
|
||||
t_TIMESEQUAL = r'\*='
|
||||
t_DIVEQUAL = r'/='
|
||||
t_MODEQUAL = r'%='
|
||||
t_PLUSEQUAL = r'\+='
|
||||
t_MINUSEQUAL = r'-='
|
||||
t_LSHIFTEQUAL = r'<<='
|
||||
t_RSHIFTEQUAL = r'>>='
|
||||
t_ANDEQUAL = r'&='
|
||||
t_OREQUAL = r'\|='
|
||||
t_XOREQUAL = r'^='
|
||||
|
||||
# Increment/decrement
|
||||
t_PLUSPLUS = r'\+\+'
|
||||
t_MINUSMINUS = r'--'
|
||||
|
||||
# ->
|
||||
t_ARROW = r'->'
|
||||
|
||||
# ?
|
||||
t_CONDOP = r'\?'
|
||||
|
||||
# Delimeters
|
||||
t_LPAREN = r'\('
|
||||
t_RPAREN = r'\)'
|
||||
t_LBRACKET = r'\['
|
||||
t_RBRACKET = r'\]'
|
||||
t_LBRACE = r'\{'
|
||||
t_RBRACE = r'\}'
|
||||
t_COMMA = r','
|
||||
t_PERIOD = r'\.'
|
||||
t_SEMI = r';'
|
||||
t_COLON = r':'
|
||||
t_ELLIPSIS = r'\.\.\.'
|
||||
|
||||
# Identifiers and reserved words
|
||||
|
||||
reserved_map = { }
|
||||
for r in reserved:
|
||||
reserved_map[r.lower()] = r
|
||||
|
||||
def t_ID(t):
|
||||
r'[A-Za-z_][\w_]*'
|
||||
t.type = reserved_map.get(t.value,"ID")
|
||||
return t
|
||||
|
||||
# Integer literal
|
||||
t_ICONST = r'\d+([uU]|[lL]|[uU][lL]|[lL][uU])?'
|
||||
|
||||
# Floating literal
|
||||
t_FCONST = r'((\d+)(\.\d+)(e(\+|-)?(\d+))? | (\d+)e(\+|-)?(\d+))([lL]|[fF])?'
|
||||
|
||||
# String literal
|
||||
t_SCONST = r'\"([^\\\n]|(\\.))*?\"'
|
||||
|
||||
# Character constant 'c' or L'c'
|
||||
t_CCONST = r'(L)?\'([^\\\n]|(\\.))*?\''
|
||||
|
||||
# Comments
|
||||
def t_comment(t):
|
||||
r' /\*(.|\n)*?\*/'
|
||||
t.lineno += t.value.count('\n')
|
||||
|
||||
# Preprocessor directive (ignored)
|
||||
def t_preprocessor(t):
|
||||
r'\#(.)*?\n'
|
||||
t.lineno += 1
|
||||
|
||||
def t_error(t):
|
||||
print "Illegal character %s" % repr(t.value[0])
|
||||
t.skip(1)
|
||||
|
||||
lexer = lex.lex(optimize=1)
|
||||
if __name__ == "__main__":
|
||||
lex.runmain(lexer)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
859
ext/ply/example/ansic/cparse.py
Normal file
859
ext/ply/example/ansic/cparse.py
Normal file
@@ -0,0 +1,859 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# cparse.py
|
||||
#
|
||||
# Simple parser for ANSI C. Based on the grammar in K&R, 2nd Ed.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
import yacc
|
||||
import clex
|
||||
|
||||
# Get the token map
|
||||
tokens = clex.tokens
|
||||
|
||||
# translation-unit:
|
||||
|
||||
def p_translation_unit_1(t):
|
||||
'translation_unit : external_declaration'
|
||||
pass
|
||||
|
||||
def p_translation_unit_2(t):
|
||||
'translation_unit : translation_unit external_declaration'
|
||||
pass
|
||||
|
||||
# external-declaration:
|
||||
|
||||
def p_external_declaration_1(t):
|
||||
'external_declaration : function_definition'
|
||||
pass
|
||||
|
||||
def p_external_declaration_2(t):
|
||||
'external_declaration : declaration'
|
||||
pass
|
||||
|
||||
# function-definition:
|
||||
|
||||
def p_function_definition_1(t):
|
||||
'function_definition : declaration_specifiers declarator declaration_list compound_statement'
|
||||
pass
|
||||
|
||||
def p_function_definition_2(t):
|
||||
'function_definition : declarator declaration_list compound_statement'
|
||||
pass
|
||||
|
||||
def p_function_definition_3(t):
|
||||
'function_definition : declarator compound_statement'
|
||||
pass
|
||||
|
||||
def p_function_definition_4(t):
|
||||
'function_definition : declaration_specifiers declarator compound_statement'
|
||||
pass
|
||||
|
||||
# declaration:
|
||||
|
||||
def p_declaration_1(t):
|
||||
'declaration : declaration_specifiers init_declarator_list SEMI'
|
||||
pass
|
||||
|
||||
def p_declaration_2(t):
|
||||
'declaration : declaration_specifiers SEMI'
|
||||
pass
|
||||
|
||||
# declaration-list:
|
||||
|
||||
def p_declaration_list_1(t):
|
||||
'declaration_list : declaration'
|
||||
pass
|
||||
|
||||
def p_declaration_list_2(t):
|
||||
'declaration_list : declaration_list declaration '
|
||||
pass
|
||||
|
||||
# declaration-specifiers
|
||||
def p_declaration_specifiers_1(t):
|
||||
'declaration_specifiers : storage_class_specifier declaration_specifiers'
|
||||
pass
|
||||
|
||||
def p_declaration_specifiers_2(t):
|
||||
'declaration_specifiers : type_specifier declaration_specifiers'
|
||||
pass
|
||||
|
||||
def p_declaration_specifiers_3(t):
|
||||
'declaration_specifiers : type_qualifier declaration_specifiers'
|
||||
pass
|
||||
|
||||
def p_declaration_specifiers_4(t):
|
||||
'declaration_specifiers : storage_class_specifier'
|
||||
pass
|
||||
|
||||
def p_declaration_specifiers_5(t):
|
||||
'declaration_specifiers : type_specifier'
|
||||
pass
|
||||
|
||||
def p_declaration_specifiers_6(t):
|
||||
'declaration_specifiers : type_qualifier'
|
||||
pass
|
||||
|
||||
# storage-class-specifier
|
||||
def p_storage_class_specifier(t):
|
||||
'''storage_class_specifier : AUTO
|
||||
| REGISTER
|
||||
| STATIC
|
||||
| EXTERN
|
||||
| TYPEDEF
|
||||
'''
|
||||
pass
|
||||
|
||||
# type-specifier:
|
||||
def p_type_specifier(t):
|
||||
'''type_specifier : VOID
|
||||
| CHAR
|
||||
| SHORT
|
||||
| INT
|
||||
| LONG
|
||||
| FLOAT
|
||||
| DOUBLE
|
||||
| SIGNED
|
||||
| UNSIGNED
|
||||
| struct_or_union_specifier
|
||||
| enum_specifier
|
||||
| TYPEID
|
||||
'''
|
||||
pass
|
||||
|
||||
# type-qualifier:
|
||||
def p_type_qualifier(t):
|
||||
'''type_qualifier : CONST
|
||||
| VOLATILE'''
|
||||
pass
|
||||
|
||||
# struct-or-union-specifier
|
||||
|
||||
def p_struct_or_union_specifier_1(t):
|
||||
'struct_or_union_specifier : struct_or_union ID LBRACE struct_declaration_list RBRACE'
|
||||
pass
|
||||
|
||||
def p_struct_or_union_specifier_2(t):
|
||||
'struct_or_union_specifier : struct_or_union LBRACE struct_declaration_list RBRACE'
|
||||
pass
|
||||
|
||||
def p_struct_or_union_specifier_3(t):
|
||||
'struct_or_union_specifier : struct_or_union ID'
|
||||
pass
|
||||
|
||||
# struct-or-union:
|
||||
def p_struct_or_union(t):
|
||||
'''struct_or_union : STRUCT
|
||||
| UNION
|
||||
'''
|
||||
pass
|
||||
|
||||
# struct-declaration-list:
|
||||
|
||||
def p_struct_declaration_list_1(t):
|
||||
'struct_declaration_list : struct_declaration'
|
||||
pass
|
||||
|
||||
def p_struct_declaration_list_2(t):
|
||||
'struct_declaration_list : struct_declarator_list struct_declaration'
|
||||
pass
|
||||
|
||||
# init-declarator-list:
|
||||
|
||||
def p_init_declarator_list_1(t):
|
||||
'init_declarator_list : init_declarator'
|
||||
pass
|
||||
|
||||
def p_init_declarator_list_2(t):
|
||||
'init_declarator_list : init_declarator_list COMMA init_declarator'
|
||||
pass
|
||||
|
||||
# init-declarator
|
||||
|
||||
def p_init_declarator_1(t):
|
||||
'init_declarator : declarator'
|
||||
pass
|
||||
|
||||
def p_init_declarator_2(t):
|
||||
'init_declarator : declarator EQUALS initializer'
|
||||
pass
|
||||
|
||||
# struct-declaration:
|
||||
|
||||
def p_struct_declaration(t):
|
||||
'struct_declaration : specifier_qualifier_list struct_declarator_list SEMI'
|
||||
pass
|
||||
|
||||
# specifier-qualifier-list:
|
||||
|
||||
def p_specifier_qualifier_list_1(t):
|
||||
'specifier_qualifier_list : type_specifier specifier_qualifier_list'
|
||||
pass
|
||||
|
||||
def p_specifier_qualifier_list_2(t):
|
||||
'specifier_qualifier_list : type_specifier'
|
||||
pass
|
||||
|
||||
def p_specifier_qualifier_list_3(t):
|
||||
'specifier_qualifier_list : type_qualifier specifier_qualifier_list'
|
||||
pass
|
||||
|
||||
def p_specifier_qualifier_list_4(t):
|
||||
'specifier_qualifier_list : type_qualifier'
|
||||
pass
|
||||
|
||||
# struct-declarator-list:
|
||||
|
||||
def p_struct_declarator_list_1(t):
|
||||
'struct_declarator_list : struct_declarator'
|
||||
pass
|
||||
|
||||
def p_struct_declarator_list_2(t):
|
||||
'struct_declarator_list : struct_declarator_list COMMA struct_declarator'
|
||||
pass
|
||||
|
||||
# struct-declarator:
|
||||
|
||||
def p_struct_declarator_1(t):
|
||||
'struct_declarator : declarator'
|
||||
pass
|
||||
|
||||
def p_struct_declarator_2(t):
|
||||
'struct_declarator : declarator COLON constant_expression'
|
||||
pass
|
||||
|
||||
def p_struct_declarator_3(t):
|
||||
'struct_declarator : COLON constant_expression'
|
||||
pass
|
||||
|
||||
# enum-specifier:
|
||||
|
||||
def p_enum_specifier_1(t):
|
||||
'enum_specifier : ENUM ID LBRACE enumerator_list RBRACE'
|
||||
pass
|
||||
|
||||
def p_enum_specifier_2(t):
|
||||
'enum_specifier : ENUM LBRACE enumerator_list RBRACE'
|
||||
pass
|
||||
|
||||
def p_enum_specifier_3(t):
|
||||
'enum_specifier : ENUM ID'
|
||||
pass
|
||||
|
||||
# enumerator_list:
|
||||
def p_enumerator_list_1(t):
|
||||
'enumerator_list : enumerator'
|
||||
pass
|
||||
|
||||
def p_enumerator_list_2(t):
|
||||
'enumerator_list : enumerator_list COMMA enumerator'
|
||||
pass
|
||||
|
||||
# enumerator:
|
||||
def p_enumerator_1(t):
|
||||
'enumerator : ID'
|
||||
pass
|
||||
|
||||
def p_enumerator_2(t):
|
||||
'enumerator : ID EQUALS constant_expression'
|
||||
pass
|
||||
|
||||
# declarator:
|
||||
|
||||
def p_declarator_1(t):
|
||||
'declarator : pointer direct_declarator'
|
||||
pass
|
||||
|
||||
def p_declarator_2(t):
|
||||
'declarator : direct_declarator'
|
||||
pass
|
||||
|
||||
# direct-declarator:
|
||||
|
||||
def p_direct_declarator_1(t):
|
||||
'direct_declarator : ID'
|
||||
pass
|
||||
|
||||
def p_direct_declarator_2(t):
|
||||
'direct_declarator : LPAREN declarator RPAREN'
|
||||
pass
|
||||
|
||||
def p_direct_declarator_3(t):
|
||||
'direct_declarator : direct_declarator LBRACKET constant_expression_opt RBRACKET'
|
||||
pass
|
||||
|
||||
def p_direct_declarator_4(t):
|
||||
'direct_declarator : direct_declarator LPAREN parameter_type_list RPAREN '
|
||||
pass
|
||||
|
||||
def p_direct_declarator_5(t):
|
||||
'direct_declarator : direct_declarator LPAREN identifier_list RPAREN '
|
||||
pass
|
||||
|
||||
def p_direct_declarator_6(t):
|
||||
'direct_declarator : direct_declarator LPAREN RPAREN '
|
||||
pass
|
||||
|
||||
# pointer:
|
||||
def p_pointer_1(t):
|
||||
'pointer : TIMES type_qualifier_list'
|
||||
pass
|
||||
|
||||
def p_pointer_2(t):
|
||||
'pointer : TIMES'
|
||||
pass
|
||||
|
||||
def p_pointer_3(t):
|
||||
'pointer : TIMES type_qualifier_list pointer'
|
||||
pass
|
||||
|
||||
def p_pointer_4(t):
|
||||
'pointer : TIMES pointer'
|
||||
pass
|
||||
|
||||
# type-qualifier-list:
|
||||
|
||||
def p_type_qualifier_list_1(t):
|
||||
'type_qualifier_list : type_qualifier'
|
||||
pass
|
||||
|
||||
def p_type_qualifier_list_2(t):
|
||||
'type_qualifier_list : type_qualifier_list type_qualifier'
|
||||
pass
|
||||
|
||||
# parameter-type-list:
|
||||
|
||||
def p_parameter_type_list_1(t):
|
||||
'parameter_type_list : parameter_list'
|
||||
pass
|
||||
|
||||
def p_parameter_type_list_2(t):
|
||||
'parameter_type_list : parameter_list COMMA ELLIPSIS'
|
||||
pass
|
||||
|
||||
# parameter-list:
|
||||
|
||||
def p_parameter_list_1(t):
|
||||
'parameter_list : parameter_declaration'
|
||||
pass
|
||||
|
||||
def p_parameter_list_2(t):
|
||||
'parameter_list : parameter_list COMMA parameter_declaration'
|
||||
pass
|
||||
|
||||
# parameter-declaration:
|
||||
def p_parameter_declaration_1(t):
|
||||
'parameter_declaration : declaration_specifiers declarator'
|
||||
pass
|
||||
|
||||
def p_parameter_declaration_2(t):
|
||||
'parameter_declaration : declaration_specifiers abstract_declarator_opt'
|
||||
pass
|
||||
|
||||
# identifier-list:
|
||||
def p_identifier_list_1(t):
|
||||
'identifier_list : ID'
|
||||
pass
|
||||
|
||||
def p_identifier_list_2(t):
|
||||
'identifier_list : identifier_list COMMA ID'
|
||||
pass
|
||||
|
||||
# initializer:
|
||||
|
||||
def p_initializer_1(t):
|
||||
'initializer : assignment_expression'
|
||||
pass
|
||||
|
||||
def p_initializer_2(t):
|
||||
'''initializer : LBRACE initializer_list RBRACE
|
||||
| LBRACE initializer_list COMMA RBRACE'''
|
||||
pass
|
||||
|
||||
# initializer-list:
|
||||
|
||||
def p_initializer_list_1(t):
|
||||
'initializer_list : initializer'
|
||||
pass
|
||||
|
||||
def p_initializer_list_2(t):
|
||||
'initializer_list : initializer_list COMMA initializer'
|
||||
pass
|
||||
|
||||
# type-name:
|
||||
|
||||
def p_type_name(t):
|
||||
'type_name : specifier_qualifier_list abstract_declarator_opt'
|
||||
pass
|
||||
|
||||
def p_abstract_declarator_opt_1(t):
|
||||
'abstract_declarator_opt : empty'
|
||||
pass
|
||||
|
||||
def p_abstract_declarator_opt_2(t):
|
||||
'abstract_declarator_opt : abstract_declarator'
|
||||
pass
|
||||
|
||||
# abstract-declarator:
|
||||
|
||||
def p_abstract_declarator_1(t):
|
||||
'abstract_declarator : pointer '
|
||||
pass
|
||||
|
||||
def p_abstract_declarator_2(t):
|
||||
'abstract_declarator : pointer direct_abstract_declarator'
|
||||
pass
|
||||
|
||||
def p_abstract_declarator_3(t):
|
||||
'abstract_declarator : direct_abstract_declarator'
|
||||
pass
|
||||
|
||||
# direct-abstract-declarator:
|
||||
|
||||
def p_direct_abstract_declarator_1(t):
|
||||
'direct_abstract_declarator : LPAREN abstract_declarator RPAREN'
|
||||
pass
|
||||
|
||||
def p_direct_abstract_declarator_2(t):
|
||||
'direct_abstract_declarator : direct_abstract_declarator LBRACKET constant_expression_opt RBRACKET'
|
||||
pass
|
||||
|
||||
def p_direct_abstract_declarator_3(t):
|
||||
'direct_abstract_declarator : LBRACKET constant_expression_opt RBRACKET'
|
||||
pass
|
||||
|
||||
def p_direct_abstract_declarator_4(t):
|
||||
'direct_abstract_declarator : direct_abstract_declarator LPAREN parameter_type_list_opt RPAREN'
|
||||
pass
|
||||
|
||||
def p_direct_abstract_declarator_5(t):
|
||||
'direct_abstract_declarator : LPAREN parameter_type_list_opt RPAREN'
|
||||
pass
|
||||
|
||||
# Optional fields in abstract declarators
|
||||
|
||||
def p_constant_expression_opt_1(t):
|
||||
'constant_expression_opt : empty'
|
||||
pass
|
||||
|
||||
def p_constant_expression_opt_2(t):
|
||||
'constant_expression_opt : constant_expression'
|
||||
pass
|
||||
|
||||
def p_parameter_type_list_opt_1(t):
|
||||
'parameter_type_list_opt : empty'
|
||||
pass
|
||||
|
||||
def p_parameter_type_list_opt_2(t):
|
||||
'parameter_type_list_opt : parameter_type_list'
|
||||
pass
|
||||
|
||||
# statement:
|
||||
|
||||
def p_statement(t):
|
||||
'''
|
||||
statement : labeled_statement
|
||||
| expression_statement
|
||||
| compound_statement
|
||||
| selection_statement
|
||||
| iteration_statement
|
||||
| jump_statement
|
||||
'''
|
||||
pass
|
||||
|
||||
# labeled-statement:
|
||||
|
||||
def p_labeled_statement_1(t):
|
||||
'labeled_statement : ID COLON statement'
|
||||
pass
|
||||
|
||||
def p_labeled_statement_2(t):
|
||||
'labeled_statement : CASE constant_expression COLON statement'
|
||||
pass
|
||||
|
||||
def p_labeled_statement_3(t):
|
||||
'labeled_statement : DEFAULT COLON statement'
|
||||
pass
|
||||
|
||||
# expression-statement:
|
||||
def p_expression_statement(t):
|
||||
'expression_statement : expression_opt SEMI'
|
||||
pass
|
||||
|
||||
# compound-statement:
|
||||
|
||||
def p_compound_statement_1(t):
|
||||
'compound_statement : LBRACE declaration_list statement_list RBRACE'
|
||||
pass
|
||||
|
||||
def p_compound_statement_2(t):
|
||||
'compound_statement : LBRACE statement_list RBRACE'
|
||||
pass
|
||||
|
||||
def p_compound_statement_3(t):
|
||||
'compound_statement : LBRACE declaration_list RBRACE'
|
||||
pass
|
||||
|
||||
def p_compound_statement_4(t):
|
||||
'compound_statement : LBRACE RBRACE'
|
||||
pass
|
||||
|
||||
# statement-list:
|
||||
|
||||
def p_statement_list_1(t):
|
||||
'statement_list : statement'
|
||||
pass
|
||||
|
||||
def p_statement_list_2(t):
|
||||
'statement_list : statement_list statement'
|
||||
pass
|
||||
|
||||
# selection-statement
|
||||
|
||||
def p_selection_statement_1(t):
|
||||
'selection_statement : IF LPAREN expression RPAREN statement'
|
||||
pass
|
||||
|
||||
def p_selection_statement_2(t):
|
||||
'selection_statement : IF LPAREN expression RPAREN statement ELSE statement '
|
||||
pass
|
||||
|
||||
def p_selection_statement_3(t):
|
||||
'selection_statement : SWITCH LPAREN expression RPAREN statement '
|
||||
pass
|
||||
|
||||
# iteration_statement:
|
||||
|
||||
def p_iteration_statement_1(t):
|
||||
'iteration_statement : WHILE LPAREN expression RPAREN statement'
|
||||
pass
|
||||
|
||||
def p_iteration_statement_2(t):
|
||||
'iteration_statement : FOR LPAREN expression_opt SEMI expression_opt SEMI expression_opt RPAREN statement '
|
||||
pass
|
||||
|
||||
def p_iteration_statement_3(t):
|
||||
'iteration_statement : DO statement WHILE LPAREN expression RPAREN SEMI'
|
||||
pass
|
||||
|
||||
# jump_statement:
|
||||
|
||||
def p_jump_statement_1(t):
|
||||
'jump_statement : GOTO ID SEMI'
|
||||
pass
|
||||
|
||||
def p_jump_statement_2(t):
|
||||
'jump_statement : CONTINUE SEMI'
|
||||
pass
|
||||
|
||||
def p_jump_statement_3(t):
|
||||
'jump_statement : BREAK SEMI'
|
||||
pass
|
||||
|
||||
def p_jump_statement_4(t):
|
||||
'jump_statement : RETURN expression_opt SEMI'
|
||||
pass
|
||||
|
||||
def p_expression_opt_1(t):
|
||||
'expression_opt : empty'
|
||||
pass
|
||||
|
||||
def p_expression_opt_2(t):
|
||||
'expression_opt : expression'
|
||||
pass
|
||||
|
||||
# expression:
|
||||
def p_expression_1(t):
|
||||
'expression : assignment_expression'
|
||||
pass
|
||||
|
||||
def p_expression_2(t):
|
||||
'expression : expression COMMA assignment_expression'
|
||||
pass
|
||||
|
||||
# assigment_expression:
|
||||
def p_assignment_expression_1(t):
|
||||
'assignment_expression : conditional_expression'
|
||||
pass
|
||||
|
||||
def p_assignment_expression_2(t):
|
||||
'assignment_expression : unary_expression assignment_operator assignment_expression'
|
||||
pass
|
||||
|
||||
# assignment_operator:
|
||||
def p_assignment_operator(t):
|
||||
'''
|
||||
assignment_operator : EQUALS
|
||||
| TIMESEQUAL
|
||||
| DIVEQUAL
|
||||
| MODEQUAL
|
||||
| PLUSEQUAL
|
||||
| MINUSEQUAL
|
||||
| LSHIFTEQUAL
|
||||
| RSHIFTEQUAL
|
||||
| ANDEQUAL
|
||||
| OREQUAL
|
||||
| XOREQUAL
|
||||
'''
|
||||
pass
|
||||
|
||||
# conditional-expression
|
||||
def p_conditional_expression_1(t):
|
||||
'conditional_expression : logical_or_expression'
|
||||
pass
|
||||
|
||||
def p_conditional_expression_2(t):
|
||||
'conditional_expression : logical_or_expression CONDOP expression COLON conditional_expression '
|
||||
pass
|
||||
|
||||
# constant-expression
|
||||
|
||||
def p_constant_expression(t):
|
||||
'constant_expression : conditional_expression'
|
||||
pass
|
||||
|
||||
# logical-or-expression
|
||||
|
||||
def p_logical_or_expression_1(t):
|
||||
'logical_or_expression : logical_and_expression'
|
||||
pass
|
||||
|
||||
def p_logical_or_expression_2(t):
|
||||
'logical_or_expression : logical_or_expression LOR logical_and_expression'
|
||||
pass
|
||||
|
||||
# logical-and-expression
|
||||
|
||||
def p_logical_and_expression_1(t):
|
||||
'logical_and_expression : inclusive_or_expression'
|
||||
pass
|
||||
|
||||
def p_logical_and_expression_2(t):
|
||||
'logical_and_expression : logical_and_expression LAND inclusive_or_expression'
|
||||
pass
|
||||
|
||||
# inclusive-or-expression:
|
||||
|
||||
def p_inclusive_or_expression_1(t):
|
||||
'inclusive_or_expression : exclusive_or_expression'
|
||||
pass
|
||||
|
||||
def p_inclusive_or_expression_2(t):
|
||||
'inclusive_or_expression : inclusive_or_expression OR exclusive_or_expression'
|
||||
pass
|
||||
|
||||
# exclusive-or-expression:
|
||||
|
||||
def p_exclusive_or_expression_1(t):
|
||||
'exclusive_or_expression : and_expression'
|
||||
pass
|
||||
|
||||
def p_exclusive_or_expression_2(t):
|
||||
'exclusive_or_expression : exclusive_or_expression XOR and_expression'
|
||||
pass
|
||||
|
||||
# AND-expression
|
||||
|
||||
def p_and_expression_1(t):
|
||||
'and_expression : equality_expression'
|
||||
pass
|
||||
|
||||
def p_and_expression_2(t):
|
||||
'and_expression : and_expression AND equality_expression'
|
||||
pass
|
||||
|
||||
|
||||
# equality-expression:
|
||||
def p_equality_expression_1(t):
|
||||
'equality_expression : relational_expression'
|
||||
pass
|
||||
|
||||
def p_equality_expression_2(t):
|
||||
'equality_expression : equality_expression EQ relational_expression'
|
||||
pass
|
||||
|
||||
def p_equality_expression_3(t):
|
||||
'equality_expression : equality_expression NE relational_expression'
|
||||
pass
|
||||
|
||||
|
||||
# relational-expression:
|
||||
def p_relational_expression_1(t):
|
||||
'relational_expression : shift_expression'
|
||||
pass
|
||||
|
||||
def p_relational_expression_2(t):
|
||||
'relational_expression : relational_expression LT shift_expression'
|
||||
pass
|
||||
|
||||
def p_relational_expression_3(t):
|
||||
'relational_expression : relational_expression GT shift_expression'
|
||||
pass
|
||||
|
||||
def p_relational_expression_4(t):
|
||||
'relational_expression : relational_expression LE shift_expression'
|
||||
pass
|
||||
|
||||
def p_relational_expression_5(t):
|
||||
'relational_expression : relational_expression GE shift_expression'
|
||||
pass
|
||||
|
||||
# shift-expression
|
||||
|
||||
def p_shift_expression_1(t):
|
||||
'shift_expression : additive_expression'
|
||||
pass
|
||||
|
||||
def p_shift_expression_2(t):
|
||||
'shift_expression : shift_expression LSHIFT additive_expression'
|
||||
pass
|
||||
|
||||
def p_shift_expression_3(t):
|
||||
'shift_expression : shift_expression RSHIFT additive_expression'
|
||||
pass
|
||||
|
||||
# additive-expression
|
||||
|
||||
def p_additive_expression_1(t):
|
||||
'additive_expression : multiplicative_expression'
|
||||
pass
|
||||
|
||||
def p_additive_expression_2(t):
|
||||
'additive_expression : additive_expression PLUS multiplicative_expression'
|
||||
pass
|
||||
|
||||
def p_additive_expression_3(t):
|
||||
'additive_expression : additive_expression MINUS multiplicative_expression'
|
||||
pass
|
||||
|
||||
# multiplicative-expression
|
||||
|
||||
def p_multiplicative_expression_1(t):
|
||||
'multiplicative_expression : cast_expression'
|
||||
pass
|
||||
|
||||
def p_multiplicative_expression_2(t):
|
||||
'multiplicative_expression : multiplicative_expression TIMES cast_expression'
|
||||
pass
|
||||
|
||||
def p_multiplicative_expression_3(t):
|
||||
'multiplicative_expression : multiplicative_expression DIVIDE cast_expression'
|
||||
pass
|
||||
|
||||
def p_multiplicative_expression_4(t):
|
||||
'multiplicative_expression : multiplicative_expression MOD cast_expression'
|
||||
pass
|
||||
|
||||
# cast-expression:
|
||||
|
||||
def p_cast_expression_1(t):
|
||||
'cast_expression : unary_expression'
|
||||
pass
|
||||
|
||||
def p_cast_expression_2(t):
|
||||
'cast_expression : LPAREN type_name RPAREN cast_expression'
|
||||
pass
|
||||
|
||||
# unary-expression:
|
||||
def p_unary_expression_1(t):
|
||||
'unary_expression : postfix_expression'
|
||||
pass
|
||||
|
||||
def p_unary_expression_2(t):
|
||||
'unary_expression : PLUSPLUS unary_expression'
|
||||
pass
|
||||
|
||||
def p_unary_expression_3(t):
|
||||
'unary_expression : MINUSMINUS unary_expression'
|
||||
pass
|
||||
|
||||
def p_unary_expression_4(t):
|
||||
'unary_expression : unary_operator cast_expression'
|
||||
pass
|
||||
|
||||
def p_unary_expression_5(t):
|
||||
'unary_expression : SIZEOF unary_expression'
|
||||
pass
|
||||
|
||||
def p_unary_expression_6(t):
|
||||
'unary_expression : SIZEOF LPAREN type_name RPAREN'
|
||||
pass
|
||||
|
||||
#unary-operator
|
||||
def p_unary_operator(t):
|
||||
'''unary_operator : AND
|
||||
| TIMES
|
||||
| PLUS
|
||||
| MINUS
|
||||
| NOT
|
||||
| LNOT '''
|
||||
pass
|
||||
|
||||
# postfix-expression:
|
||||
def p_postfix_expression_1(t):
|
||||
'postfix_expression : primary_expression'
|
||||
pass
|
||||
|
||||
def p_postfix_expression_2(t):
|
||||
'postfix_expression : postfix_expression LBRACKET expression RBRACKET'
|
||||
pass
|
||||
|
||||
def p_postfix_expression_3(t):
|
||||
'postfix_expression : postfix_expression LPAREN argument_expression_list RPAREN'
|
||||
pass
|
||||
|
||||
def p_postfix_expression_4(t):
|
||||
'postfix_expression : postfix_expression LPAREN RPAREN'
|
||||
pass
|
||||
|
||||
def p_postfix_expression_5(t):
|
||||
'postfix_expression : postfix_expression PERIOD ID'
|
||||
pass
|
||||
|
||||
def p_postfix_expression_6(t):
|
||||
'postfix_expression : postfix_expression ARROW ID'
|
||||
pass
|
||||
|
||||
def p_postfix_expression_7(t):
|
||||
'postfix_expression : postfix_expression PLUSPLUS'
|
||||
pass
|
||||
|
||||
def p_postfix_expression_8(t):
|
||||
'postfix_expression : postfix_expression MINUSMINUS'
|
||||
pass
|
||||
|
||||
# primary-expression:
|
||||
def p_primary_expression(t):
|
||||
'''primary_expression : ID
|
||||
| constant
|
||||
| SCONST
|
||||
| LPAREN expression RPAREN'''
|
||||
pass
|
||||
|
||||
# argument-expression-list:
|
||||
def p_argument_expression_list(t):
|
||||
'''argument_expression_list : assignment_expression
|
||||
| argument_expression_list COMMA assignment_expression'''
|
||||
pass
|
||||
|
||||
# constant:
|
||||
def p_constant(t):
|
||||
'''constant : ICONST
|
||||
| FCONST
|
||||
| CCONST'''
|
||||
pass
|
||||
|
||||
|
||||
def p_empty(t):
|
||||
'empty : '
|
||||
pass
|
||||
|
||||
def p_error(t):
|
||||
print "Whoa. We're hosed"
|
||||
|
||||
import profile
|
||||
# Build the grammar
|
||||
profile.run("yacc.yacc()")
|
||||
|
||||
|
||||
|
||||
|
||||
108
ext/ply/example/calc/calc.py
Normal file
108
ext/ply/example/calc/calc.py
Normal file
@@ -0,0 +1,108 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# calc.py
|
||||
#
|
||||
# A simple calculator with variables. This is from O'Reilly's
|
||||
# "Lex and Yacc", p. 63.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
tokens = (
|
||||
'NAME','NUMBER',
|
||||
'PLUS','MINUS','TIMES','DIVIDE','EQUALS',
|
||||
'LPAREN','RPAREN',
|
||||
)
|
||||
|
||||
# Tokens
|
||||
|
||||
t_PLUS = r'\+'
|
||||
t_MINUS = r'-'
|
||||
t_TIMES = r'\*'
|
||||
t_DIVIDE = r'/'
|
||||
t_EQUALS = r'='
|
||||
t_LPAREN = r'\('
|
||||
t_RPAREN = r'\)'
|
||||
t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
|
||||
|
||||
def t_NUMBER(t):
|
||||
r'\d+'
|
||||
try:
|
||||
t.value = int(t.value)
|
||||
except ValueError:
|
||||
print "Integer value too large", t.value
|
||||
t.value = 0
|
||||
return t
|
||||
|
||||
t_ignore = " \t"
|
||||
|
||||
def t_newline(t):
|
||||
r'\n+'
|
||||
t.lineno += t.value.count("\n")
|
||||
|
||||
def t_error(t):
|
||||
print "Illegal character '%s'" % t.value[0]
|
||||
t.skip(1)
|
||||
|
||||
# Build the lexer
|
||||
import lex
|
||||
lex.lex()
|
||||
|
||||
# Parsing rules
|
||||
|
||||
precedence = (
|
||||
('left','PLUS','MINUS'),
|
||||
('left','TIMES','DIVIDE'),
|
||||
('right','UMINUS'),
|
||||
)
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
def p_statement_assign(t):
|
||||
'statement : NAME EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement_expr(t):
|
||||
'statement : expression'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[2] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
def p_error(t):
|
||||
print "Syntax error at '%s'" % t.value
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
while 1:
|
||||
try:
|
||||
s = raw_input('calc > ')
|
||||
except EOFError:
|
||||
break
|
||||
yacc.parse(s)
|
||||
44
ext/ply/example/hedit/hedit.py
Normal file
44
ext/ply/example/hedit/hedit.py
Normal file
@@ -0,0 +1,44 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# hedit.py
|
||||
#
|
||||
# Paring of Fortran H Edit descriptions (Contributed by Pearu Peterson)
|
||||
#
|
||||
# These tokens can't be easily tokenized because they are of the following
|
||||
# form:
|
||||
#
|
||||
# nHc1...cn
|
||||
#
|
||||
# where n is a positive integer and c1 ... cn are characters.
|
||||
#
|
||||
# This example shows how to modify the state of the lexer to parse
|
||||
# such tokens
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
tokens = (
|
||||
'H_EDIT_DESCRIPTOR',
|
||||
)
|
||||
|
||||
# Tokens
|
||||
t_ignore = " \t\n"
|
||||
|
||||
def t_H_EDIT_DESCRIPTOR(t):
|
||||
r"\d+H.*" # This grabs all of the remaining text
|
||||
i = t.value.index('H')
|
||||
n = eval(t.value[:i])
|
||||
|
||||
# Adjust the tokenizing position
|
||||
t.lexer.lexpos -= len(t.value) - (i+1+n)
|
||||
|
||||
t.value = t.value[i+1:i+1+n]
|
||||
return t
|
||||
|
||||
def t_error(t):
|
||||
print "Illegal character '%s'" % t.value[0]
|
||||
t.skip(1)
|
||||
|
||||
# Build the lexer
|
||||
import lex
|
||||
lex.lex()
|
||||
lex.runmain()
|
||||
|
||||
|
||||
9
ext/ply/example/optcalc/README
Normal file
9
ext/ply/example/optcalc/README
Normal file
@@ -0,0 +1,9 @@
|
||||
An example showing how to use Python optimized mode.
|
||||
To run:
|
||||
|
||||
- First run 'python calc.py'
|
||||
|
||||
- Then run 'python -OO calc.py'
|
||||
|
||||
If working corretly, the second version should run the
|
||||
same way.
|
||||
110
ext/ply/example/optcalc/calc.py
Normal file
110
ext/ply/example/optcalc/calc.py
Normal file
@@ -0,0 +1,110 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# calc.py
|
||||
#
|
||||
# A simple calculator with variables. This is from O'Reilly's
|
||||
# "Lex and Yacc", p. 63.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
tokens = (
|
||||
'NAME','NUMBER',
|
||||
'PLUS','MINUS','TIMES','DIVIDE','EQUALS',
|
||||
'LPAREN','RPAREN',
|
||||
)
|
||||
|
||||
# Tokens
|
||||
|
||||
t_PLUS = r'\+'
|
||||
t_MINUS = r'-'
|
||||
t_TIMES = r'\*'
|
||||
t_DIVIDE = r'/'
|
||||
t_EQUALS = r'='
|
||||
t_LPAREN = r'\('
|
||||
t_RPAREN = r'\)'
|
||||
t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
|
||||
|
||||
def t_NUMBER(t):
|
||||
r'\d+'
|
||||
try:
|
||||
t.value = int(t.value)
|
||||
except ValueError:
|
||||
print "Integer value too large", t.value
|
||||
t.value = 0
|
||||
return t
|
||||
|
||||
t_ignore = " \t"
|
||||
|
||||
def t_newline(t):
|
||||
r'\n+'
|
||||
t.lineno += t.value.count("\n")
|
||||
|
||||
def t_error(t):
|
||||
print "Illegal character '%s'" % t.value[0]
|
||||
t.skip(1)
|
||||
|
||||
# Build the lexer
|
||||
import lex
|
||||
lex.lex(optimize=1)
|
||||
|
||||
# Parsing rules
|
||||
|
||||
precedence = (
|
||||
('left','PLUS','MINUS'),
|
||||
('left','TIMES','DIVIDE'),
|
||||
('right','UMINUS'),
|
||||
)
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
def p_statement_assign(t):
|
||||
'statement : NAME EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement_expr(t):
|
||||
'statement : expression'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[2] == '/': t[0] = t[1] / t[3]
|
||||
elif t[2] == '<': t[0] = t[1] < t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
def p_error(t):
|
||||
print "Syntax error at '%s'" % t.value
|
||||
|
||||
import yacc
|
||||
yacc.yacc(optimize=1)
|
||||
|
||||
while 1:
|
||||
try:
|
||||
s = raw_input('calc > ')
|
||||
except EOFError:
|
||||
break
|
||||
yacc.parse(s)
|
||||
|
||||
681
ext/ply/lex.py
Normal file
681
ext/ply/lex.py
Normal file
@@ -0,0 +1,681 @@
|
||||
#-----------------------------------------------------------------------------
|
||||
# ply: lex.py
|
||||
#
|
||||
# Author: David M. Beazley (beazley@cs.uchicago.edu)
|
||||
# Department of Computer Science
|
||||
# University of Chicago
|
||||
# Chicago, IL 60637
|
||||
#
|
||||
# Copyright (C) 2001, David M. Beazley
|
||||
#
|
||||
# $Header: /home/stever/bk/newmem2/ext/ply/lex.py 1.1 03/06/06 14:53:34-00:00 stever@ $
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# See the file COPYING for a complete copy of the LGPL.
|
||||
#
|
||||
#
|
||||
# This module automatically constructs a lexical analysis module from regular
|
||||
# expression rules defined in a user-defined module. The idea is essentially the same
|
||||
# as that used in John Aycock's Spark framework, but the implementation works
|
||||
# at the module level rather than requiring the use of classes.
|
||||
#
|
||||
# This module tries to provide an interface that is closely modeled after
|
||||
# the traditional lex interface in Unix. It also differs from Spark
|
||||
# in that:
|
||||
#
|
||||
# - It provides more extensive error checking and reporting if
|
||||
# the user supplies a set of regular expressions that can't
|
||||
# be compiled or if there is any other kind of a problem in
|
||||
# the specification.
|
||||
#
|
||||
# - The interface is geared towards LALR(1) and LR(1) parser
|
||||
# generators. That is tokens are generated one at a time
|
||||
# rather than being generated in advanced all in one step.
|
||||
#
|
||||
# There are a few limitations of this module
|
||||
#
|
||||
# - The module interface makes it somewhat awkward to support more
|
||||
# than one lexer at a time. Although somewhat inelegant from a
|
||||
# design perspective, this is rarely a practical concern for
|
||||
# most compiler projects.
|
||||
#
|
||||
# - The lexer requires that the entire input text be read into
|
||||
# a string before scanning. I suppose that most machines have
|
||||
# enough memory to make this a minor issues, but it makes
|
||||
# the lexer somewhat difficult to use in interactive sessions
|
||||
# or with streaming data.
|
||||
#
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
r"""
|
||||
lex.py
|
||||
|
||||
This module builds lex-like scanners based on regular expression rules.
|
||||
To use the module, simply write a collection of regular expression rules
|
||||
and actions like this:
|
||||
|
||||
# lexer.py
|
||||
import lex
|
||||
|
||||
# Define a list of valid tokens
|
||||
tokens = (
|
||||
'IDENTIFIER', 'NUMBER', 'PLUS', 'MINUS'
|
||||
)
|
||||
|
||||
# Define tokens as functions
|
||||
def t_IDENTIFIER(t):
|
||||
r' ([a-zA-Z_](\w|_)* '
|
||||
return t
|
||||
|
||||
def t_NUMBER(t):
|
||||
r' \d+ '
|
||||
return t
|
||||
|
||||
# Some simple tokens with no actions
|
||||
t_PLUS = r'\+'
|
||||
t_MINUS = r'-'
|
||||
|
||||
# Initialize the lexer
|
||||
lex.lex()
|
||||
|
||||
The tokens list is required and contains a complete list of all valid
|
||||
token types that the lexer is allowed to produce. Token types are
|
||||
restricted to be valid identifiers. This means that 'MINUS' is a valid
|
||||
token type whereas '-' is not.
|
||||
|
||||
Rules are defined by writing a function with a name of the form
|
||||
t_rulename. Each rule must accept a single argument which is
|
||||
a token object generated by the lexer. This token has the following
|
||||
attributes:
|
||||
|
||||
t.type = type string of the token. This is initially set to the
|
||||
name of the rule without the leading t_
|
||||
t.value = The value of the lexeme.
|
||||
t.lineno = The value of the line number where the token was encountered
|
||||
|
||||
For example, the t_NUMBER() rule above might be called with the following:
|
||||
|
||||
t.type = 'NUMBER'
|
||||
t.value = '42'
|
||||
t.lineno = 3
|
||||
|
||||
Each rule returns the token object it would like to supply to the
|
||||
parser. In most cases, the token t is returned with few, if any
|
||||
modifications. To discard a token for things like whitespace or
|
||||
comments, simply return nothing. For instance:
|
||||
|
||||
def t_whitespace(t):
|
||||
r' \s+ '
|
||||
pass
|
||||
|
||||
For faster lexing, you can also define this in terms of the ignore set like this:
|
||||
|
||||
t_ignore = ' \t'
|
||||
|
||||
The characters in this string are ignored by the lexer. Use of this feature can speed
|
||||
up parsing significantly since scanning will immediately proceed to the next token.
|
||||
|
||||
lex requires that the token returned by each rule has an attribute
|
||||
t.type. Other than this, rules are free to return any kind of token
|
||||
object that they wish and may construct a new type of token object
|
||||
from the attributes of t (provided the new object has the required
|
||||
type attribute).
|
||||
|
||||
If illegal characters are encountered, the scanner executes the
|
||||
function t_error(t) where t is a token representing the rest of the
|
||||
string that hasn't been matched. If this function isn't defined, a
|
||||
LexError exception is raised. The .text attribute of this exception
|
||||
object contains the part of the string that wasn't matched.
|
||||
|
||||
The t.skip(n) method can be used to skip ahead n characters in the
|
||||
input stream. This is usually only used in the error handling rule.
|
||||
For instance, the following rule would print an error message and
|
||||
continue:
|
||||
|
||||
def t_error(t):
|
||||
print "Illegal character in input %s" % t.value[0]
|
||||
t.skip(1)
|
||||
|
||||
Of course, a nice scanner might wish to skip more than one character
|
||||
if the input looks very corrupted.
|
||||
|
||||
The lex module defines a t.lineno attribute on each token that can be used
|
||||
to track the current line number in the input. The value of this
|
||||
variable is not modified by lex so it is up to your lexer module
|
||||
to correctly update its value depending on the lexical properties
|
||||
of the input language. To do this, you might write rules such as
|
||||
the following:
|
||||
|
||||
def t_newline(t):
|
||||
r' \n+ '
|
||||
t.lineno += t.value.count("\n")
|
||||
|
||||
To initialize your lexer so that it can be used, simply call the lex.lex()
|
||||
function in your rule file. If there are any errors in your
|
||||
specification, warning messages or an exception will be generated to
|
||||
alert you to the problem.
|
||||
|
||||
(dave: this needs to be rewritten)
|
||||
To use the newly constructed lexer from another module, simply do
|
||||
this:
|
||||
|
||||
import lex
|
||||
import lexer
|
||||
plex.input("position = initial + rate*60")
|
||||
|
||||
while 1:
|
||||
token = plex.token() # Get a token
|
||||
if not token: break # No more tokens
|
||||
... do whatever ...
|
||||
|
||||
Assuming that the module 'lexer' has initialized plex as shown
|
||||
above, parsing modules can safely import 'plex' without having
|
||||
to import the rule file or any additional imformation about the
|
||||
scanner you have defined.
|
||||
"""
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
__version__ = "1.3"
|
||||
|
||||
import re, types, sys, copy
|
||||
|
||||
# Exception thrown when invalid token encountered and no default
|
||||
class LexError(Exception):
|
||||
def __init__(self,message,s):
|
||||
self.args = (message,)
|
||||
self.text = s
|
||||
|
||||
# Token class
|
||||
class LexToken:
|
||||
def __str__(self):
|
||||
return "LexToken(%s,%r,%d)" % (self.type,self.value,self.lineno)
|
||||
def __repr__(self):
|
||||
return str(self)
|
||||
def skip(self,n):
|
||||
try:
|
||||
self._skipn += n
|
||||
except AttributeError:
|
||||
self._skipn = n
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Lexer class
|
||||
#
|
||||
# input() - Store a new string in the lexer
|
||||
# token() - Get the next token
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
class Lexer:
|
||||
def __init__(self):
|
||||
self.lexre = None # Master regular expression
|
||||
self.lexdata = None # Actual input data (as a string)
|
||||
self.lexpos = 0 # Current position in input text
|
||||
self.lexlen = 0 # Length of the input text
|
||||
self.lexindexfunc = [ ] # Reverse mapping of groups to functions and types
|
||||
self.lexerrorf = None # Error rule (if any)
|
||||
self.lextokens = None # List of valid tokens
|
||||
self.lexignore = None # Ignored characters
|
||||
self.lineno = 1 # Current line number
|
||||
self.debug = 0 # Debugging mode
|
||||
self.optimize = 0 # Optimized mode
|
||||
self.token = self.errtoken
|
||||
|
||||
def __copy__(self):
|
||||
c = Lexer()
|
||||
c.lexre = self.lexre
|
||||
c.lexdata = self.lexdata
|
||||
c.lexpos = self.lexpos
|
||||
c.lexlen = self.lexlen
|
||||
c.lenindexfunc = self.lexindexfunc
|
||||
c.lexerrorf = self.lexerrorf
|
||||
c.lextokens = self.lextokens
|
||||
c.lexignore = self.lexignore
|
||||
c.lineno = self.lineno
|
||||
c.optimize = self.optimize
|
||||
c.token = c.realtoken
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# input() - Push a new string into the lexer
|
||||
# ------------------------------------------------------------
|
||||
def input(self,s):
|
||||
if not isinstance(s,types.StringType):
|
||||
raise ValueError, "Expected a string"
|
||||
self.lexdata = s
|
||||
self.lexpos = 0
|
||||
self.lexlen = len(s)
|
||||
self.token = self.realtoken
|
||||
|
||||
# Change the token routine to point to realtoken()
|
||||
global token
|
||||
if token == self.errtoken:
|
||||
token = self.token
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# errtoken() - Return error if token is called with no data
|
||||
# ------------------------------------------------------------
|
||||
def errtoken(self):
|
||||
raise RuntimeError, "No input string given with input()"
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# token() - Return the next token from the Lexer
|
||||
#
|
||||
# Note: This function has been carefully implemented to be as fast
|
||||
# as possible. Don't make changes unless you really know what
|
||||
# you are doing
|
||||
# ------------------------------------------------------------
|
||||
def realtoken(self):
|
||||
# Make local copies of frequently referenced attributes
|
||||
lexpos = self.lexpos
|
||||
lexlen = self.lexlen
|
||||
lexignore = self.lexignore
|
||||
lexdata = self.lexdata
|
||||
|
||||
while lexpos < lexlen:
|
||||
# This code provides some short-circuit code for whitespace, tabs, and other ignored characters
|
||||
if lexdata[lexpos] in lexignore:
|
||||
lexpos += 1
|
||||
continue
|
||||
|
||||
# Look for a regular expression match
|
||||
m = self.lexre.match(lexdata,lexpos)
|
||||
if m:
|
||||
i = m.lastindex
|
||||
lexpos = m.end()
|
||||
tok = LexToken()
|
||||
tok.value = m.group()
|
||||
tok.lineno = self.lineno
|
||||
tok.lexer = self
|
||||
func,tok.type = self.lexindexfunc[i]
|
||||
if not func:
|
||||
self.lexpos = lexpos
|
||||
return tok
|
||||
|
||||
# If token is processed by a function, call it
|
||||
self.lexpos = lexpos
|
||||
newtok = func(tok)
|
||||
self.lineno = tok.lineno # Update line number
|
||||
|
||||
# Every function must return a token, if nothing, we just move to next token
|
||||
if not newtok: continue
|
||||
|
||||
# Verify type of the token. If not in the token map, raise an error
|
||||
if not self.optimize:
|
||||
if not self.lextokens.has_key(newtok.type):
|
||||
raise LexError, ("%s:%d: Rule '%s' returned an unknown token type '%s'" % (
|
||||
func.func_code.co_filename, func.func_code.co_firstlineno,
|
||||
func.__name__, newtok.type),lexdata[lexpos:])
|
||||
|
||||
return newtok
|
||||
|
||||
# No match. Call t_error() if defined.
|
||||
if self.lexerrorf:
|
||||
tok = LexToken()
|
||||
tok.value = self.lexdata[lexpos:]
|
||||
tok.lineno = self.lineno
|
||||
tok.type = "error"
|
||||
tok.lexer = self
|
||||
oldpos = lexpos
|
||||
newtok = self.lexerrorf(tok)
|
||||
lexpos += getattr(tok,"_skipn",0)
|
||||
if oldpos == lexpos:
|
||||
# Error method didn't change text position at all. This is an error.
|
||||
self.lexpos = lexpos
|
||||
raise LexError, ("Scanning error. Illegal character '%s'" % (lexdata[lexpos]), lexdata[lexpos:])
|
||||
if not newtok: continue
|
||||
self.lexpos = lexpos
|
||||
return newtok
|
||||
|
||||
self.lexpos = lexpos
|
||||
raise LexError, ("No match found", lexdata[lexpos:])
|
||||
|
||||
# No more input data
|
||||
self.lexpos = lexpos + 1
|
||||
return None
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# validate_file()
|
||||
#
|
||||
# This checks to see if there are duplicated t_rulename() functions or strings
|
||||
# in the parser input file. This is done using a simple regular expression
|
||||
# match on each line in the filename.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def validate_file(filename):
|
||||
import os.path
|
||||
base,ext = os.path.splitext(filename)
|
||||
if ext != '.py': return 1 # No idea what the file is. Return OK
|
||||
|
||||
try:
|
||||
f = open(filename)
|
||||
lines = f.readlines()
|
||||
f.close()
|
||||
except IOError:
|
||||
return 1 # Oh well
|
||||
|
||||
fre = re.compile(r'\s*def\s+(t_[a-zA-Z_0-9]*)\(')
|
||||
sre = re.compile(r'\s*(t_[a-zA-Z_0-9]*)\s*=')
|
||||
counthash = { }
|
||||
linen = 1
|
||||
noerror = 1
|
||||
for l in lines:
|
||||
m = fre.match(l)
|
||||
if not m:
|
||||
m = sre.match(l)
|
||||
if m:
|
||||
name = m.group(1)
|
||||
prev = counthash.get(name)
|
||||
if not prev:
|
||||
counthash[name] = linen
|
||||
else:
|
||||
print "%s:%d: Rule %s redefined. Previously defined on line %d" % (filename,linen,name,prev)
|
||||
noerror = 0
|
||||
linen += 1
|
||||
return noerror
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# _read_lextab(module)
|
||||
#
|
||||
# Reads lexer table from a lextab file instead of using introspection.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def _read_lextab(lexer, fdict, module):
|
||||
exec "import %s as lextab" % module
|
||||
lexer.lexre = re.compile(lextab._lexre, re.VERBOSE)
|
||||
lexer.lexindexfunc = lextab._lextab
|
||||
for i in range(len(lextab._lextab)):
|
||||
t = lexer.lexindexfunc[i]
|
||||
if t:
|
||||
if t[0]:
|
||||
lexer.lexindexfunc[i] = (fdict[t[0]],t[1])
|
||||
lexer.lextokens = lextab._lextokens
|
||||
lexer.lexignore = lextab._lexignore
|
||||
if lextab._lexerrorf:
|
||||
lexer.lexerrorf = fdict[lextab._lexerrorf]
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# lex(module)
|
||||
#
|
||||
# Build all of the regular expression rules from definitions in the supplied module
|
||||
# -----------------------------------------------------------------------------
|
||||
def lex(module=None,debug=0,optimize=0,lextab="lextab"):
|
||||
ldict = None
|
||||
regex = ""
|
||||
error = 0
|
||||
files = { }
|
||||
lexer = Lexer()
|
||||
lexer.debug = debug
|
||||
lexer.optimize = optimize
|
||||
global token,input
|
||||
|
||||
if module:
|
||||
if not isinstance(module, types.ModuleType):
|
||||
raise ValueError,"Expected a module"
|
||||
|
||||
ldict = module.__dict__
|
||||
|
||||
else:
|
||||
# No module given. We might be able to get information from the caller.
|
||||
try:
|
||||
raise RuntimeError
|
||||
except RuntimeError:
|
||||
e,b,t = sys.exc_info()
|
||||
f = t.tb_frame
|
||||
f = f.f_back # Walk out to our calling function
|
||||
ldict = f.f_globals # Grab its globals dictionary
|
||||
|
||||
if optimize and lextab:
|
||||
try:
|
||||
_read_lextab(lexer,ldict, lextab)
|
||||
if not lexer.lexignore: lexer.lexignore = ""
|
||||
token = lexer.token
|
||||
input = lexer.input
|
||||
return lexer
|
||||
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# Get the tokens map
|
||||
tokens = ldict.get("tokens",None)
|
||||
if not tokens:
|
||||
raise SyntaxError,"lex: module does not define 'tokens'"
|
||||
if not (isinstance(tokens,types.ListType) or isinstance(tokens,types.TupleType)):
|
||||
raise SyntaxError,"lex: tokens must be a list or tuple."
|
||||
|
||||
# Build a dictionary of valid token names
|
||||
lexer.lextokens = { }
|
||||
if not optimize:
|
||||
|
||||
# Utility function for verifying tokens
|
||||
def is_identifier(s):
|
||||
for c in s:
|
||||
if not (c.isalnum() or c == '_'): return 0
|
||||
return 1
|
||||
|
||||
for n in tokens:
|
||||
if not is_identifier(n):
|
||||
print "lex: Bad token name '%s'" % n
|
||||
error = 1
|
||||
if lexer.lextokens.has_key(n):
|
||||
print "lex: Warning. Token '%s' multiply defined." % n
|
||||
lexer.lextokens[n] = None
|
||||
else:
|
||||
for n in tokens: lexer.lextokens[n] = None
|
||||
|
||||
|
||||
if debug:
|
||||
print "lex: tokens = '%s'" % lexer.lextokens.keys()
|
||||
|
||||
# Get a list of symbols with the t_ prefix
|
||||
tsymbols = [f for f in ldict.keys() if f[:2] == 't_']
|
||||
|
||||
# Now build up a list of functions and a list of strings
|
||||
fsymbols = [ ]
|
||||
ssymbols = [ ]
|
||||
for f in tsymbols:
|
||||
if isinstance(ldict[f],types.FunctionType):
|
||||
fsymbols.append(ldict[f])
|
||||
elif isinstance(ldict[f],types.StringType):
|
||||
ssymbols.append((f,ldict[f]))
|
||||
else:
|
||||
print "lex: %s not defined as a function or string" % f
|
||||
error = 1
|
||||
|
||||
# Sort the functions by line number
|
||||
fsymbols.sort(lambda x,y: cmp(x.func_code.co_firstlineno,y.func_code.co_firstlineno))
|
||||
|
||||
# Sort the strings by regular expression length
|
||||
ssymbols.sort(lambda x,y: (len(x[1]) < len(y[1])) - (len(x[1]) > len(y[1])))
|
||||
|
||||
# Check for non-empty symbols
|
||||
if len(fsymbols) == 0 and len(ssymbols) == 0:
|
||||
raise SyntaxError,"lex: no rules of the form t_rulename are defined."
|
||||
|
||||
# Add all of the rules defined with actions first
|
||||
for f in fsymbols:
|
||||
|
||||
line = f.func_code.co_firstlineno
|
||||
file = f.func_code.co_filename
|
||||
files[file] = None
|
||||
|
||||
if not optimize:
|
||||
if f.func_code.co_argcount > 1:
|
||||
print "%s:%d: Rule '%s' has too many arguments." % (file,line,f.__name__)
|
||||
error = 1
|
||||
continue
|
||||
|
||||
if f.func_code.co_argcount < 1:
|
||||
print "%s:%d: Rule '%s' requires an argument." % (file,line,f.__name__)
|
||||
error = 1
|
||||
continue
|
||||
|
||||
if f.__name__ == 't_ignore':
|
||||
print "%s:%d: Rule '%s' must be defined as a string." % (file,line,f.__name__)
|
||||
error = 1
|
||||
continue
|
||||
|
||||
if f.__name__ == 't_error':
|
||||
lexer.lexerrorf = f
|
||||
continue
|
||||
|
||||
if f.__doc__:
|
||||
if not optimize:
|
||||
try:
|
||||
c = re.compile(f.__doc__, re.VERBOSE)
|
||||
except re.error,e:
|
||||
print "%s:%d: Invalid regular expression for rule '%s'. %s" % (file,line,f.__name__,e)
|
||||
error = 1
|
||||
continue
|
||||
|
||||
if debug:
|
||||
print "lex: Adding rule %s -> '%s'" % (f.__name__,f.__doc__)
|
||||
|
||||
# Okay. The regular expression seemed okay. Let's append it to the master regular
|
||||
# expression we're building
|
||||
|
||||
if (regex): regex += "|"
|
||||
regex += "(?P<%s>%s)" % (f.__name__,f.__doc__)
|
||||
else:
|
||||
print "%s:%d: No regular expression defined for rule '%s'" % (file,line,f.__name__)
|
||||
|
||||
# Now add all of the simple rules
|
||||
for name,r in ssymbols:
|
||||
|
||||
if name == 't_ignore':
|
||||
lexer.lexignore = r
|
||||
continue
|
||||
|
||||
if not optimize:
|
||||
if name == 't_error':
|
||||
raise SyntaxError,"lex: Rule 't_error' must be defined as a function"
|
||||
error = 1
|
||||
continue
|
||||
|
||||
if not lexer.lextokens.has_key(name[2:]):
|
||||
print "lex: Rule '%s' defined for an unspecified token %s." % (name,name[2:])
|
||||
error = 1
|
||||
continue
|
||||
try:
|
||||
c = re.compile(r,re.VERBOSE)
|
||||
except re.error,e:
|
||||
print "lex: Invalid regular expression for rule '%s'. %s" % (name,e)
|
||||
error = 1
|
||||
continue
|
||||
if debug:
|
||||
print "lex: Adding rule %s -> '%s'" % (name,r)
|
||||
|
||||
if regex: regex += "|"
|
||||
regex += "(?P<%s>%s)" % (name,r)
|
||||
|
||||
if not optimize:
|
||||
for f in files.keys():
|
||||
if not validate_file(f):
|
||||
error = 1
|
||||
try:
|
||||
if debug:
|
||||
print "lex: regex = '%s'" % regex
|
||||
lexer.lexre = re.compile(regex, re.VERBOSE)
|
||||
|
||||
# Build the index to function map for the matching engine
|
||||
lexer.lexindexfunc = [ None ] * (max(lexer.lexre.groupindex.values())+1)
|
||||
for f,i in lexer.lexre.groupindex.items():
|
||||
handle = ldict[f]
|
||||
if isinstance(handle,types.FunctionType):
|
||||
lexer.lexindexfunc[i] = (handle,handle.__name__[2:])
|
||||
else:
|
||||
# If rule was specified as a string, we build an anonymous
|
||||
# callback function to carry out the action
|
||||
lexer.lexindexfunc[i] = (None,f[2:])
|
||||
|
||||
# If a lextab was specified, we create a file containing the precomputed
|
||||
# regular expression and index table
|
||||
|
||||
if lextab and optimize:
|
||||
lt = open(lextab+".py","w")
|
||||
lt.write("# %s.py. This file automatically created by PLY. Don't edit.\n" % lextab)
|
||||
lt.write("_lexre = %s\n" % repr(regex))
|
||||
lt.write("_lextab = [\n");
|
||||
for i in range(0,len(lexer.lexindexfunc)):
|
||||
t = lexer.lexindexfunc[i]
|
||||
if t:
|
||||
if t[0]:
|
||||
lt.write(" ('%s',%s),\n"% (t[0].__name__, repr(t[1])))
|
||||
else:
|
||||
lt.write(" (None,%s),\n" % repr(t[1]))
|
||||
else:
|
||||
lt.write(" None,\n")
|
||||
|
||||
lt.write("]\n");
|
||||
lt.write("_lextokens = %s\n" % repr(lexer.lextokens))
|
||||
lt.write("_lexignore = %s\n" % repr(lexer.lexignore))
|
||||
if (lexer.lexerrorf):
|
||||
lt.write("_lexerrorf = %s\n" % repr(lexer.lexerrorf.__name__))
|
||||
else:
|
||||
lt.write("_lexerrorf = None\n")
|
||||
lt.close()
|
||||
|
||||
except re.error,e:
|
||||
print "lex: Fatal error. Unable to compile regular expression rules. %s" % e
|
||||
error = 1
|
||||
if error:
|
||||
raise SyntaxError,"lex: Unable to build lexer."
|
||||
if not lexer.lexerrorf:
|
||||
print "lex: Warning. no t_error rule is defined."
|
||||
|
||||
if not lexer.lexignore: lexer.lexignore = ""
|
||||
|
||||
# Create global versions of the token() and input() functions
|
||||
token = lexer.token
|
||||
input = lexer.input
|
||||
|
||||
return lexer
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# run()
|
||||
#
|
||||
# This runs the lexer as a main program
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def runmain(lexer=None,data=None):
|
||||
if not data:
|
||||
try:
|
||||
filename = sys.argv[1]
|
||||
f = open(filename)
|
||||
data = f.read()
|
||||
f.close()
|
||||
except IndexError:
|
||||
print "Reading from standard input (type EOF to end):"
|
||||
data = sys.stdin.read()
|
||||
|
||||
if lexer:
|
||||
_input = lexer.input
|
||||
else:
|
||||
_input = input
|
||||
_input(data)
|
||||
if lexer:
|
||||
_token = lexer.token
|
||||
else:
|
||||
_token = token
|
||||
|
||||
while 1:
|
||||
tok = _token()
|
||||
if not tok: break
|
||||
print "(%s,'%s',%d)" % (tok.type, tok.value, tok.lineno)
|
||||
|
||||
|
||||
|
||||
|
||||
9
ext/ply/test/README
Normal file
9
ext/ply/test/README
Normal file
@@ -0,0 +1,9 @@
|
||||
This directory mostly contains tests for various types of error
|
||||
conditions. To run:
|
||||
|
||||
$ python testlex.py .
|
||||
$ python testyacc.py .
|
||||
|
||||
(make sure lex.py and yacc.py exist in this directory before
|
||||
running the tests).
|
||||
|
||||
46
ext/ply/test/calclex.py
Normal file
46
ext/ply/test/calclex.py
Normal file
@@ -0,0 +1,46 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# calclex.py
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
tokens = (
|
||||
'NAME','NUMBER',
|
||||
'PLUS','MINUS','TIMES','DIVIDE','EQUALS',
|
||||
'LPAREN','RPAREN',
|
||||
)
|
||||
|
||||
# Tokens
|
||||
|
||||
t_PLUS = r'\+'
|
||||
t_MINUS = r'-'
|
||||
t_TIMES = r'\*'
|
||||
t_DIVIDE = r'/'
|
||||
t_EQUALS = r'='
|
||||
t_LPAREN = r'\('
|
||||
t_RPAREN = r'\)'
|
||||
t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
|
||||
|
||||
def t_NUMBER(t):
|
||||
r'\d+'
|
||||
try:
|
||||
t.value = int(t.value)
|
||||
except ValueError:
|
||||
print "Integer value too large", t.value
|
||||
t.value = 0
|
||||
return t
|
||||
|
||||
t_ignore = " \t"
|
||||
|
||||
def t_newline(t):
|
||||
r'\n+'
|
||||
t.lineno += t.value.count("\n")
|
||||
|
||||
def t_error(t):
|
||||
print "Illegal character '%s'" % t.value[0]
|
||||
t.skip(1)
|
||||
|
||||
# Build the lexer
|
||||
import lex
|
||||
lex.lex()
|
||||
|
||||
|
||||
|
||||
1
ext/ply/test/lex_doc1.exp
Normal file
1
ext/ply/test/lex_doc1.exp
Normal file
@@ -0,0 +1 @@
|
||||
./lex_doc1.py:15: No regular expression defined for rule 't_NUMBER'
|
||||
27
ext/ply/test/lex_doc1.py
Normal file
27
ext/ply/test/lex_doc1.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# lex_token.py
|
||||
#
|
||||
# Missing documentation string
|
||||
|
||||
import lex
|
||||
|
||||
tokens = [
|
||||
"PLUS",
|
||||
"MINUS",
|
||||
"NUMBER",
|
||||
]
|
||||
|
||||
t_PLUS = r'\+'
|
||||
t_MINUS = r'-'
|
||||
def t_NUMBER(t):
|
||||
pass
|
||||
|
||||
def t_error(t):
|
||||
pass
|
||||
|
||||
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
lex.lex()
|
||||
|
||||
|
||||
2
ext/ply/test/lex_dup1.exp
Normal file
2
ext/ply/test/lex_dup1.exp
Normal file
@@ -0,0 +1,2 @@
|
||||
./lex_dup1.py:17: Rule t_NUMBER redefined. Previously defined on line 15
|
||||
SyntaxError: lex: Unable to build lexer.
|
||||
27
ext/ply/test/lex_dup1.py
Normal file
27
ext/ply/test/lex_dup1.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# lex_token.py
|
||||
#
|
||||
# Duplicated rule specifiers
|
||||
|
||||
import lex
|
||||
|
||||
tokens = [
|
||||
"PLUS",
|
||||
"MINUS",
|
||||
"NUMBER",
|
||||
]
|
||||
|
||||
t_PLUS = r'\+'
|
||||
t_MINUS = r'-'
|
||||
t_NUMBER = r'\d+'
|
||||
|
||||
t_NUMBER = r'\d+'
|
||||
|
||||
def t_error(t):
|
||||
pass
|
||||
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
lex.lex()
|
||||
|
||||
|
||||
2
ext/ply/test/lex_dup2.exp
Normal file
2
ext/ply/test/lex_dup2.exp
Normal file
@@ -0,0 +1,2 @@
|
||||
./lex_dup2.py:19: Rule t_NUMBER redefined. Previously defined on line 15
|
||||
SyntaxError: lex: Unable to build lexer.
|
||||
31
ext/ply/test/lex_dup2.py
Normal file
31
ext/ply/test/lex_dup2.py
Normal file
@@ -0,0 +1,31 @@
|
||||
# lex_token.py
|
||||
#
|
||||
# Duplicated rule specifiers
|
||||
|
||||
import lex
|
||||
|
||||
tokens = [
|
||||
"PLUS",
|
||||
"MINUS",
|
||||
"NUMBER",
|
||||
]
|
||||
|
||||
t_PLUS = r'\+'
|
||||
t_MINUS = r'-'
|
||||
def t_NUMBER(t):
|
||||
r'\d+'
|
||||
pass
|
||||
|
||||
def t_NUMBER(t):
|
||||
r'\d+'
|
||||
pass
|
||||
|
||||
def t_error(t):
|
||||
pass
|
||||
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
lex.lex()
|
||||
|
||||
|
||||
2
ext/ply/test/lex_dup3.exp
Normal file
2
ext/ply/test/lex_dup3.exp
Normal file
@@ -0,0 +1,2 @@
|
||||
./lex_dup3.py:17: Rule t_NUMBER redefined. Previously defined on line 15
|
||||
SyntaxError: lex: Unable to build lexer.
|
||||
29
ext/ply/test/lex_dup3.py
Normal file
29
ext/ply/test/lex_dup3.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# lex_token.py
|
||||
#
|
||||
# Duplicated rule specifiers
|
||||
|
||||
import lex
|
||||
|
||||
tokens = [
|
||||
"PLUS",
|
||||
"MINUS",
|
||||
"NUMBER",
|
||||
]
|
||||
|
||||
t_PLUS = r'\+'
|
||||
t_MINUS = r'-'
|
||||
t_NUMBER = r'\d+'
|
||||
|
||||
def t_NUMBER(t):
|
||||
r'\d+'
|
||||
pass
|
||||
|
||||
def t_error(t):
|
||||
pass
|
||||
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
lex.lex()
|
||||
|
||||
|
||||
1
ext/ply/test/lex_empty.exp
Normal file
1
ext/ply/test/lex_empty.exp
Normal file
@@ -0,0 +1 @@
|
||||
SyntaxError: lex: no rules of the form t_rulename are defined.
|
||||
18
ext/ply/test/lex_empty.py
Normal file
18
ext/ply/test/lex_empty.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# lex_token.py
|
||||
#
|
||||
# No rules defined
|
||||
|
||||
import lex
|
||||
|
||||
tokens = [
|
||||
"PLUS",
|
||||
"MINUS",
|
||||
"NUMBER",
|
||||
]
|
||||
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
lex.lex()
|
||||
|
||||
|
||||
1
ext/ply/test/lex_error1.exp
Normal file
1
ext/ply/test/lex_error1.exp
Normal file
@@ -0,0 +1 @@
|
||||
lex: Warning. no t_error rule is defined.
|
||||
22
ext/ply/test/lex_error1.py
Normal file
22
ext/ply/test/lex_error1.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# lex_token.py
|
||||
#
|
||||
# Missing t_error() rule
|
||||
|
||||
import lex
|
||||
|
||||
tokens = [
|
||||
"PLUS",
|
||||
"MINUS",
|
||||
"NUMBER",
|
||||
]
|
||||
|
||||
t_PLUS = r'\+'
|
||||
t_MINUS = r'-'
|
||||
t_NUMBER = r'\d+'
|
||||
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
lex.lex()
|
||||
|
||||
|
||||
1
ext/ply/test/lex_error2.exp
Normal file
1
ext/ply/test/lex_error2.exp
Normal file
@@ -0,0 +1 @@
|
||||
SyntaxError: lex: Rule 't_error' must be defined as a function
|
||||
24
ext/ply/test/lex_error2.py
Normal file
24
ext/ply/test/lex_error2.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# lex_token.py
|
||||
#
|
||||
# t_error defined, but not function
|
||||
|
||||
import lex
|
||||
|
||||
tokens = [
|
||||
"PLUS",
|
||||
"MINUS",
|
||||
"NUMBER",
|
||||
]
|
||||
|
||||
t_PLUS = r'\+'
|
||||
t_MINUS = r'-'
|
||||
t_NUMBER = r'\d+'
|
||||
|
||||
t_error = "foo"
|
||||
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
lex.lex()
|
||||
|
||||
|
||||
2
ext/ply/test/lex_error3.exp
Normal file
2
ext/ply/test/lex_error3.exp
Normal file
@@ -0,0 +1,2 @@
|
||||
./lex_error3.py:17: Rule 't_error' requires an argument.
|
||||
SyntaxError: lex: Unable to build lexer.
|
||||
25
ext/ply/test/lex_error3.py
Normal file
25
ext/ply/test/lex_error3.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# lex_token.py
|
||||
#
|
||||
# t_error defined as function, but with wrong # args
|
||||
|
||||
import lex
|
||||
|
||||
tokens = [
|
||||
"PLUS",
|
||||
"MINUS",
|
||||
"NUMBER",
|
||||
]
|
||||
|
||||
t_PLUS = r'\+'
|
||||
t_MINUS = r'-'
|
||||
t_NUMBER = r'\d+'
|
||||
|
||||
def t_error():
|
||||
pass
|
||||
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
lex.lex()
|
||||
|
||||
|
||||
2
ext/ply/test/lex_error4.exp
Normal file
2
ext/ply/test/lex_error4.exp
Normal file
@@ -0,0 +1,2 @@
|
||||
./lex_error4.py:17: Rule 't_error' has too many arguments.
|
||||
SyntaxError: lex: Unable to build lexer.
|
||||
25
ext/ply/test/lex_error4.py
Normal file
25
ext/ply/test/lex_error4.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# lex_token.py
|
||||
#
|
||||
# t_error defined as function, but too many args
|
||||
|
||||
import lex
|
||||
|
||||
tokens = [
|
||||
"PLUS",
|
||||
"MINUS",
|
||||
"NUMBER",
|
||||
]
|
||||
|
||||
t_PLUS = r'\+'
|
||||
t_MINUS = r'-'
|
||||
t_NUMBER = r'\d+'
|
||||
|
||||
def t_error(t,s):
|
||||
pass
|
||||
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
lex.lex()
|
||||
|
||||
|
||||
3
ext/ply/test/lex_hedit.exp
Normal file
3
ext/ply/test/lex_hedit.exp
Normal file
@@ -0,0 +1,3 @@
|
||||
(H_EDIT_DESCRIPTOR,'abc',1)
|
||||
(H_EDIT_DESCRIPTOR,'abcdefghij',1)
|
||||
(H_EDIT_DESCRIPTOR,'xy',1)
|
||||
44
ext/ply/test/lex_hedit.py
Normal file
44
ext/ply/test/lex_hedit.py
Normal file
@@ -0,0 +1,44 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# hedit.py
|
||||
#
|
||||
# Paring of Fortran H Edit descriptions (Contributed by Pearu Peterson)
|
||||
#
|
||||
# These tokens can't be easily tokenized because they are of the following
|
||||
# form:
|
||||
#
|
||||
# nHc1...cn
|
||||
#
|
||||
# where n is a positive integer and c1 ... cn are characters.
|
||||
#
|
||||
# This example shows how to modify the state of the lexer to parse
|
||||
# such tokens
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
tokens = (
|
||||
'H_EDIT_DESCRIPTOR',
|
||||
)
|
||||
|
||||
# Tokens
|
||||
t_ignore = " \t\n"
|
||||
|
||||
def t_H_EDIT_DESCRIPTOR(t):
|
||||
r"\d+H.*" # This grabs all of the remaining text
|
||||
i = t.value.index('H')
|
||||
n = eval(t.value[:i])
|
||||
|
||||
# Adjust the tokenizing position
|
||||
t.lexer.lexpos -= len(t.value) - (i+1+n)
|
||||
t.value = t.value[i+1:i+1+n]
|
||||
return t
|
||||
|
||||
def t_error(t):
|
||||
print "Illegal character '%s'" % t.value[0]
|
||||
t.skip(1)
|
||||
|
||||
# Build the lexer
|
||||
import lex
|
||||
lex.lex()
|
||||
lex.runmain(data="3Habc 10Habcdefghij 2Hxy")
|
||||
|
||||
|
||||
|
||||
2
ext/ply/test/lex_ignore.exp
Normal file
2
ext/ply/test/lex_ignore.exp
Normal file
@@ -0,0 +1,2 @@
|
||||
./lex_ignore.py:17: Rule 't_ignore' must be defined as a string.
|
||||
SyntaxError: lex: Unable to build lexer.
|
||||
29
ext/ply/test/lex_ignore.py
Normal file
29
ext/ply/test/lex_ignore.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# lex_token.py
|
||||
#
|
||||
# Improperly specific ignore declaration
|
||||
|
||||
import lex
|
||||
|
||||
tokens = [
|
||||
"PLUS",
|
||||
"MINUS",
|
||||
"NUMBER",
|
||||
]
|
||||
|
||||
t_PLUS = r'\+'
|
||||
t_MINUS = r'-'
|
||||
t_NUMBER = r'\d+'
|
||||
|
||||
def t_ignore(t):
|
||||
' \t'
|
||||
pass
|
||||
|
||||
def t_error(t):
|
||||
pass
|
||||
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
lex.lex()
|
||||
|
||||
|
||||
2
ext/ply/test/lex_re1.exp
Normal file
2
ext/ply/test/lex_re1.exp
Normal file
@@ -0,0 +1,2 @@
|
||||
lex: Invalid regular expression for rule 't_NUMBER'. unbalanced parenthesis
|
||||
SyntaxError: lex: Unable to build lexer.
|
||||
25
ext/ply/test/lex_re1.py
Normal file
25
ext/ply/test/lex_re1.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# lex_token.py
|
||||
#
|
||||
# Bad regular expression in a string
|
||||
|
||||
import lex
|
||||
|
||||
tokens = [
|
||||
"PLUS",
|
||||
"MINUS",
|
||||
"NUMBER",
|
||||
]
|
||||
|
||||
t_PLUS = r'\+'
|
||||
t_MINUS = r'-'
|
||||
t_NUMBER = r'(\d+'
|
||||
|
||||
def t_error(t):
|
||||
pass
|
||||
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
lex.lex()
|
||||
|
||||
|
||||
2
ext/ply/test/lex_rule1.exp
Normal file
2
ext/ply/test/lex_rule1.exp
Normal file
@@ -0,0 +1,2 @@
|
||||
lex: t_NUMBER not defined as a function or string
|
||||
SyntaxError: lex: Unable to build lexer.
|
||||
25
ext/ply/test/lex_rule1.py
Normal file
25
ext/ply/test/lex_rule1.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# lex_token.py
|
||||
#
|
||||
# Rule defined as some other type
|
||||
|
||||
import lex
|
||||
|
||||
tokens = [
|
||||
"PLUS",
|
||||
"MINUS",
|
||||
"NUMBER",
|
||||
]
|
||||
|
||||
t_PLUS = r'\+'
|
||||
t_MINUS = r'-'
|
||||
t_NUMBER = 1
|
||||
|
||||
def t_error(t):
|
||||
pass
|
||||
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
lex.lex()
|
||||
|
||||
|
||||
1
ext/ply/test/lex_token1.exp
Normal file
1
ext/ply/test/lex_token1.exp
Normal file
@@ -0,0 +1 @@
|
||||
SyntaxError: lex: module does not define 'tokens'
|
||||
19
ext/ply/test/lex_token1.py
Normal file
19
ext/ply/test/lex_token1.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# lex_token.py
|
||||
#
|
||||
# Tests for absence of tokens variable
|
||||
|
||||
import lex
|
||||
|
||||
t_PLUS = r'\+'
|
||||
t_MINUS = r'-'
|
||||
t_NUMBER = r'\d+'
|
||||
|
||||
def t_error(t):
|
||||
pass
|
||||
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
lex.lex()
|
||||
|
||||
|
||||
1
ext/ply/test/lex_token2.exp
Normal file
1
ext/ply/test/lex_token2.exp
Normal file
@@ -0,0 +1 @@
|
||||
SyntaxError: lex: tokens must be a list or tuple.
|
||||
21
ext/ply/test/lex_token2.py
Normal file
21
ext/ply/test/lex_token2.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# lex_token.py
|
||||
#
|
||||
# Tests for tokens of wrong type
|
||||
|
||||
import lex
|
||||
|
||||
tokens = "PLUS MINUS NUMBER"
|
||||
|
||||
t_PLUS = r'\+'
|
||||
t_MINUS = r'-'
|
||||
t_NUMBER = r'\d+'
|
||||
|
||||
def t_error(t):
|
||||
pass
|
||||
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
lex.lex()
|
||||
|
||||
|
||||
2
ext/ply/test/lex_token3.exp
Normal file
2
ext/ply/test/lex_token3.exp
Normal file
@@ -0,0 +1,2 @@
|
||||
lex: Rule 't_MINUS' defined for an unspecified token MINUS.
|
||||
SyntaxError: lex: Unable to build lexer.
|
||||
24
ext/ply/test/lex_token3.py
Normal file
24
ext/ply/test/lex_token3.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# lex_token.py
|
||||
#
|
||||
# tokens is right type, but is missing a token for one rule
|
||||
|
||||
import lex
|
||||
|
||||
tokens = [
|
||||
"PLUS",
|
||||
"NUMBER",
|
||||
]
|
||||
|
||||
t_PLUS = r'\+'
|
||||
t_MINUS = r'-'
|
||||
t_NUMBER = r'\d+'
|
||||
|
||||
def t_error(t):
|
||||
pass
|
||||
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
lex.lex()
|
||||
|
||||
|
||||
2
ext/ply/test/lex_token4.exp
Normal file
2
ext/ply/test/lex_token4.exp
Normal file
@@ -0,0 +1,2 @@
|
||||
lex: Bad token name '-'
|
||||
SyntaxError: lex: Unable to build lexer.
|
||||
26
ext/ply/test/lex_token4.py
Normal file
26
ext/ply/test/lex_token4.py
Normal file
@@ -0,0 +1,26 @@
|
||||
# lex_token.py
|
||||
#
|
||||
# Bad token name
|
||||
|
||||
import lex
|
||||
|
||||
tokens = [
|
||||
"PLUS",
|
||||
"MINUS",
|
||||
"-",
|
||||
"NUMBER",
|
||||
]
|
||||
|
||||
t_PLUS = r'\+'
|
||||
t_MINUS = r'-'
|
||||
t_NUMBER = r'\d+'
|
||||
|
||||
def t_error(t):
|
||||
pass
|
||||
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
lex.lex()
|
||||
|
||||
|
||||
1
ext/ply/test/lex_token5.exp
Normal file
1
ext/ply/test/lex_token5.exp
Normal file
@@ -0,0 +1 @@
|
||||
lex.LexError: ./lex_token5.py:16: Rule 't_NUMBER' returned an unknown token type 'NUM'
|
||||
31
ext/ply/test/lex_token5.py
Normal file
31
ext/ply/test/lex_token5.py
Normal file
@@ -0,0 +1,31 @@
|
||||
# lex_token.py
|
||||
#
|
||||
# Return a bad token name
|
||||
|
||||
import lex
|
||||
|
||||
tokens = [
|
||||
"PLUS",
|
||||
"MINUS",
|
||||
"NUMBER",
|
||||
]
|
||||
|
||||
t_PLUS = r'\+'
|
||||
t_MINUS = r'-'
|
||||
|
||||
def t_NUMBER(t):
|
||||
r'\d+'
|
||||
t.type = "NUM"
|
||||
return t
|
||||
|
||||
def t_error(t):
|
||||
pass
|
||||
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
lex.lex()
|
||||
lex.input("1234")
|
||||
t = lex.token()
|
||||
|
||||
|
||||
57
ext/ply/test/testlex.py
Executable file
57
ext/ply/test/testlex.py
Executable file
@@ -0,0 +1,57 @@
|
||||
#!/usr/local/bin
|
||||
# ----------------------------------------------------------------------
|
||||
# testlex.py
|
||||
#
|
||||
# Run tests for the lexing module
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
import sys,os,glob
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print "Usage: python testlex.py directory"
|
||||
raise SystemExit
|
||||
|
||||
dirname = None
|
||||
make = 0
|
||||
|
||||
for o in sys.argv[1:]:
|
||||
if o == '-make':
|
||||
make = 1
|
||||
else:
|
||||
dirname = o
|
||||
break
|
||||
|
||||
if not dirname:
|
||||
print "Usage: python testlex.py [-make] directory"
|
||||
raise SystemExit
|
||||
|
||||
f = glob.glob("%s/%s" % (dirname,"lex_*.py"))
|
||||
|
||||
print "**** Running tests for lex ****"
|
||||
|
||||
for t in f:
|
||||
name = t[:-3]
|
||||
print "Testing %-32s" % name,
|
||||
if make:
|
||||
if not os.path.exists("%s.exp" % name):
|
||||
os.system("python %s.py >%s.exp 2>&1" % (name,name))
|
||||
passed = 1
|
||||
else:
|
||||
os.system("python %s.py >%s.out 2>&1" % (name,name))
|
||||
a = os.system("diff %s.out %s.exp >%s.dif" % (name,name,name))
|
||||
if a == 0:
|
||||
passed = 1
|
||||
else:
|
||||
passed = 0
|
||||
|
||||
if passed:
|
||||
print "Passed"
|
||||
else:
|
||||
print "Failed. See %s.dif" % name
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
58
ext/ply/test/testyacc.py
Normal file
58
ext/ply/test/testyacc.py
Normal file
@@ -0,0 +1,58 @@
|
||||
#!/usr/local/bin
|
||||
# ----------------------------------------------------------------------
|
||||
# testyacc.py
|
||||
#
|
||||
# Run tests for the yacc module
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
import sys,os,glob
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print "Usage: python testyacc.py directory"
|
||||
raise SystemExit
|
||||
|
||||
dirname = None
|
||||
make = 0
|
||||
|
||||
for o in sys.argv[1:]:
|
||||
if o == '-make':
|
||||
make = 1
|
||||
else:
|
||||
dirname = o
|
||||
break
|
||||
|
||||
if not dirname:
|
||||
print "Usage: python testyacc.py [-make] directory"
|
||||
raise SystemExit
|
||||
|
||||
f = glob.glob("%s/%s" % (dirname,"yacc_*.py"))
|
||||
|
||||
print "**** Running tests for yacc ****"
|
||||
|
||||
for t in f:
|
||||
name = t[:-3]
|
||||
print "Testing %-32s" % name,
|
||||
os.system("rm -f %s/parsetab.*" % dirname)
|
||||
if make:
|
||||
if not os.path.exists("%s.exp" % name):
|
||||
os.system("python %s.py >%s.exp 2>&1" % (name,name))
|
||||
passed = 1
|
||||
else:
|
||||
os.system("python %s.py >%s.out 2>&1" % (name,name))
|
||||
a = os.system("diff %s.out %s.exp >%s.dif" % (name,name,name))
|
||||
if a == 0:
|
||||
passed = 1
|
||||
else:
|
||||
passed = 0
|
||||
|
||||
if passed:
|
||||
print "Passed"
|
||||
else:
|
||||
print "Failed. See %s.dif" % name
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
3
ext/ply/test/yacc_badargs.exp
Normal file
3
ext/ply/test/yacc_badargs.exp
Normal file
@@ -0,0 +1,3 @@
|
||||
./yacc_badargs.py:21: Rule 'p_statement_assign' has too many arguments.
|
||||
./yacc_badargs.py:25: Rule 'p_statement_expr' requires an argument.
|
||||
yacc.YaccError: Unable to construct parser.
|
||||
67
ext/ply/test/yacc_badargs.py
Normal file
67
ext/ply/test/yacc_badargs.py
Normal file
@@ -0,0 +1,67 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# yacc_badargs.py
|
||||
#
|
||||
# Rules with wrong # args
|
||||
# -----------------------------------------------------------------------------
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
from calclex import tokens
|
||||
|
||||
# Parsing rules
|
||||
precedence = (
|
||||
('left','PLUS','MINUS'),
|
||||
('left','TIMES','DIVIDE'),
|
||||
('right','UMINUS'),
|
||||
)
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
def p_statement_assign(t,s):
|
||||
'statement : NAME EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement_expr():
|
||||
'statement : expression'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[3] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
def p_error(t):
|
||||
print "Syntax error at '%s'" % t.value
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
|
||||
|
||||
|
||||
1
ext/ply/test/yacc_badprec.exp
Normal file
1
ext/ply/test/yacc_badprec.exp
Normal file
@@ -0,0 +1 @@
|
||||
yacc.YaccError: precedence must be a list or tuple.
|
||||
63
ext/ply/test/yacc_badprec.py
Normal file
63
ext/ply/test/yacc_badprec.py
Normal file
@@ -0,0 +1,63 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# yacc_badprec.py
|
||||
#
|
||||
# Bad precedence specifier
|
||||
# -----------------------------------------------------------------------------
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
from calclex import tokens
|
||||
|
||||
# Parsing rules
|
||||
precedence = "blah"
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
def p_statement_assign(t):
|
||||
'statement : NAME EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement_expr(t):
|
||||
'statement : expression'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[3] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
def p_error(t):
|
||||
print "Syntax error at '%s'" % t.value
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
|
||||
|
||||
|
||||
3
ext/ply/test/yacc_badprec2.exp
Normal file
3
ext/ply/test/yacc_badprec2.exp
Normal file
@@ -0,0 +1,3 @@
|
||||
yacc: Invalid precedence table.
|
||||
yacc: Generating SLR parsing table...
|
||||
yacc: 4 shift/reduce conflicts
|
||||
67
ext/ply/test/yacc_badprec2.py
Normal file
67
ext/ply/test/yacc_badprec2.py
Normal file
@@ -0,0 +1,67 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# yacc_badprec2.py
|
||||
#
|
||||
# Bad precedence
|
||||
# -----------------------------------------------------------------------------
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
from calclex import tokens
|
||||
|
||||
# Parsing rules
|
||||
precedence = (
|
||||
42,
|
||||
('left','TIMES','DIVIDE'),
|
||||
('right','UMINUS'),
|
||||
)
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
def p_statement_assign(t):
|
||||
'statement : NAME EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement_expr(t):
|
||||
'statement : expression'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[3] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
def p_error(t):
|
||||
print "Syntax error at '%s'" % t.value
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
|
||||
|
||||
|
||||
5
ext/ply/test/yacc_badrule.exp
Normal file
5
ext/ply/test/yacc_badrule.exp
Normal file
@@ -0,0 +1,5 @@
|
||||
./yacc_badrule.py:22: Syntax error. Expected ':'
|
||||
./yacc_badrule.py:26: Syntax error in rule 'statement'
|
||||
./yacc_badrule.py:31: Syntax error. Expected ':'
|
||||
./yacc_badrule.py:40: Syntax error. Expected ':'
|
||||
yacc.YaccError: Unable to construct parser.
|
||||
67
ext/ply/test/yacc_badrule.py
Normal file
67
ext/ply/test/yacc_badrule.py
Normal file
@@ -0,0 +1,67 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# yacc_badrule.py
|
||||
#
|
||||
# Syntax problems in the rule strings
|
||||
# -----------------------------------------------------------------------------
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
from calclex import tokens
|
||||
|
||||
# Parsing rules
|
||||
precedence = (
|
||||
('left','PLUS','MINUS'),
|
||||
('left','TIMES','DIVIDE'),
|
||||
('right','UMINUS'),
|
||||
)
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
def p_statement_assign(t):
|
||||
'statement NAME EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement_expr(t):
|
||||
'statement'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[3] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression: MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
def p_error(t):
|
||||
print "Syntax error at '%s'" % t.value
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
|
||||
|
||||
|
||||
1
ext/ply/test/yacc_badtok.exp
Normal file
1
ext/ply/test/yacc_badtok.exp
Normal file
@@ -0,0 +1 @@
|
||||
yacc.YaccError: tokens must be a list or tuple.
|
||||
68
ext/ply/test/yacc_badtok.py
Normal file
68
ext/ply/test/yacc_badtok.py
Normal file
@@ -0,0 +1,68 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# yacc_badtok.py
|
||||
#
|
||||
# A grammar, but tokens is a bad datatype
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
tokens = "Hello"
|
||||
|
||||
# Parsing rules
|
||||
precedence = (
|
||||
('left','PLUS','MINUS'),
|
||||
('left','TIMES','DIVIDE'),
|
||||
('right','UMINUS'),
|
||||
)
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
def p_statement_assign(t):
|
||||
'statement : NAME EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement_expr(t):
|
||||
'statement : expression'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[3] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
def p_error(t):
|
||||
print "Syntax error at '%s'" % t.value
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
|
||||
|
||||
|
||||
4
ext/ply/test/yacc_dup.exp
Normal file
4
ext/ply/test/yacc_dup.exp
Normal file
@@ -0,0 +1,4 @@
|
||||
./yacc_dup.py:25: Function p_statement redefined. Previously defined on line 21
|
||||
yacc: Warning. Token 'EQUALS' defined, but not used.
|
||||
yacc: Warning. There is 1 unused token.
|
||||
yacc: Generating SLR parsing table...
|
||||
67
ext/ply/test/yacc_dup.py
Normal file
67
ext/ply/test/yacc_dup.py
Normal file
@@ -0,0 +1,67 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# yacc_dup.py
|
||||
#
|
||||
# Duplicated rule name
|
||||
# -----------------------------------------------------------------------------
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
from calclex import tokens
|
||||
|
||||
# Parsing rules
|
||||
precedence = (
|
||||
('left','PLUS','MINUS'),
|
||||
('left','TIMES','DIVIDE'),
|
||||
('right','UMINUS'),
|
||||
)
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
def p_statement(t):
|
||||
'statement : NAME EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement(t):
|
||||
'statement : expression'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[3] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
def p_error(t):
|
||||
print "Syntax error at '%s'" % t.value
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
|
||||
|
||||
|
||||
1
ext/ply/test/yacc_error1.exp
Normal file
1
ext/ply/test/yacc_error1.exp
Normal file
@@ -0,0 +1 @@
|
||||
yacc.YaccError: ./yacc_error1.py:59: p_error() requires 1 argument.
|
||||
67
ext/ply/test/yacc_error1.py
Normal file
67
ext/ply/test/yacc_error1.py
Normal file
@@ -0,0 +1,67 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# yacc_error1.py
|
||||
#
|
||||
# Bad p_error() function
|
||||
# -----------------------------------------------------------------------------
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
from calclex import tokens
|
||||
|
||||
# Parsing rules
|
||||
precedence = (
|
||||
('left','PLUS','MINUS'),
|
||||
('left','TIMES','DIVIDE'),
|
||||
('right','UMINUS'),
|
||||
)
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
def p_statement_assign(t):
|
||||
'statement : NAME EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement_expr(t):
|
||||
'statement : expression'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[3] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
def p_error(t,s):
|
||||
print "Syntax error at '%s'" % t.value
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
|
||||
|
||||
|
||||
1
ext/ply/test/yacc_error2.exp
Normal file
1
ext/ply/test/yacc_error2.exp
Normal file
@@ -0,0 +1 @@
|
||||
yacc.YaccError: ./yacc_error2.py:59: p_error() requires 1 argument.
|
||||
67
ext/ply/test/yacc_error2.py
Normal file
67
ext/ply/test/yacc_error2.py
Normal file
@@ -0,0 +1,67 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# yacc_error1.py
|
||||
#
|
||||
# Bad p_error() function
|
||||
# -----------------------------------------------------------------------------
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
from calclex import tokens
|
||||
|
||||
# Parsing rules
|
||||
precedence = (
|
||||
('left','PLUS','MINUS'),
|
||||
('left','TIMES','DIVIDE'),
|
||||
('right','UMINUS'),
|
||||
)
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
def p_statement_assign(t):
|
||||
'statement : NAME EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement_expr(t):
|
||||
'statement : expression'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[3] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
def p_error():
|
||||
print "Syntax error at '%s'" % t.value
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
|
||||
|
||||
|
||||
1
ext/ply/test/yacc_error3.exp
Normal file
1
ext/ply/test/yacc_error3.exp
Normal file
@@ -0,0 +1 @@
|
||||
yacc.YaccError: 'p_error' defined, but is not a function.
|
||||
66
ext/ply/test/yacc_error3.py
Normal file
66
ext/ply/test/yacc_error3.py
Normal file
@@ -0,0 +1,66 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# yacc_error1.py
|
||||
#
|
||||
# Bad p_error() function
|
||||
# -----------------------------------------------------------------------------
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
from calclex import tokens
|
||||
|
||||
# Parsing rules
|
||||
precedence = (
|
||||
('left','PLUS','MINUS'),
|
||||
('left','TIMES','DIVIDE'),
|
||||
('right','UMINUS'),
|
||||
)
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
def p_statement_assign(t):
|
||||
'statement : NAME EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement_expr(t):
|
||||
'statement : expression'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[3] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
p_error = "blah"
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
|
||||
|
||||
|
||||
5
ext/ply/test/yacc_inf.exp
Normal file
5
ext/ply/test/yacc_inf.exp
Normal file
@@ -0,0 +1,5 @@
|
||||
yacc: Warning. Token 'NUMBER' defined, but not used.
|
||||
yacc: Warning. There is 1 unused token.
|
||||
yacc: Infinite recursion detected for symbol 'statement'.
|
||||
yacc: Infinite recursion detected for symbol 'expression'.
|
||||
yacc.YaccError: Unable to construct parser.
|
||||
55
ext/ply/test/yacc_inf.py
Normal file
55
ext/ply/test/yacc_inf.py
Normal file
@@ -0,0 +1,55 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# yacc_inf.py
|
||||
#
|
||||
# Infinite recursion
|
||||
# -----------------------------------------------------------------------------
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
from calclex import tokens
|
||||
|
||||
# Parsing rules
|
||||
precedence = (
|
||||
('left','PLUS','MINUS'),
|
||||
('left','TIMES','DIVIDE'),
|
||||
('right','UMINUS'),
|
||||
)
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
def p_statement_assign(t):
|
||||
'statement : NAME EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement_expr(t):
|
||||
'statement : expression'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[3] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_error(t):
|
||||
print "Syntax error at '%s'" % t.value
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
|
||||
|
||||
|
||||
2
ext/ply/test/yacc_missing1.exp
Normal file
2
ext/ply/test/yacc_missing1.exp
Normal file
@@ -0,0 +1,2 @@
|
||||
./yacc_missing1.py:22: Symbol 'location' used, but not defined as a token or a rule.
|
||||
yacc.YaccError: Unable to construct parser.
|
||||
67
ext/ply/test/yacc_missing1.py
Normal file
67
ext/ply/test/yacc_missing1.py
Normal file
@@ -0,0 +1,67 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# yacc_missing1.py
|
||||
#
|
||||
# Grammar with a missing rule
|
||||
# -----------------------------------------------------------------------------
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
from calclex import tokens
|
||||
|
||||
# Parsing rules
|
||||
precedence = (
|
||||
('left','PLUS','MINUS'),
|
||||
('left','TIMES','DIVIDE'),
|
||||
('right','UMINUS'),
|
||||
)
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
def p_statement_assign(t):
|
||||
'statement : location EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement_expr(t):
|
||||
'statement : expression'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[3] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
def p_error(t):
|
||||
print "Syntax error at '%s'" % t.value
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
|
||||
|
||||
|
||||
2
ext/ply/test/yacc_nodoc.exp
Normal file
2
ext/ply/test/yacc_nodoc.exp
Normal file
@@ -0,0 +1,2 @@
|
||||
./yacc_nodoc.py:25: No documentation string specified in function 'p_statement_expr'
|
||||
yacc: Generating SLR parsing table...
|
||||
66
ext/ply/test/yacc_nodoc.py
Normal file
66
ext/ply/test/yacc_nodoc.py
Normal file
@@ -0,0 +1,66 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# yacc_nodoc.py
|
||||
#
|
||||
# Rule with a missing doc-string
|
||||
# -----------------------------------------------------------------------------
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
from calclex import tokens
|
||||
|
||||
# Parsing rules
|
||||
precedence = (
|
||||
('left','PLUS','MINUS'),
|
||||
('left','TIMES','DIVIDE'),
|
||||
('right','UMINUS'),
|
||||
)
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
def p_statement_assign(t):
|
||||
'statement : NAME EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement_expr(t):
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[3] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
def p_error(t):
|
||||
print "Syntax error at '%s'" % t.value
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
|
||||
|
||||
|
||||
2
ext/ply/test/yacc_noerror.exp
Normal file
2
ext/ply/test/yacc_noerror.exp
Normal file
@@ -0,0 +1,2 @@
|
||||
yacc: Warning. no p_error() function is defined.
|
||||
yacc: Generating SLR parsing table...
|
||||
64
ext/ply/test/yacc_noerror.py
Normal file
64
ext/ply/test/yacc_noerror.py
Normal file
@@ -0,0 +1,64 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# yacc_noerror.py
|
||||
#
|
||||
# No p_error() rule defined.
|
||||
# -----------------------------------------------------------------------------
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
from calclex import tokens
|
||||
|
||||
# Parsing rules
|
||||
precedence = (
|
||||
('left','PLUS','MINUS'),
|
||||
('left','TIMES','DIVIDE'),
|
||||
('right','UMINUS'),
|
||||
)
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
def p_statement_assign(t):
|
||||
'statement : NAME EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement_expr(t):
|
||||
'statement : expression'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[3] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
|
||||
|
||||
|
||||
2
ext/ply/test/yacc_nop.exp
Normal file
2
ext/ply/test/yacc_nop.exp
Normal file
@@ -0,0 +1,2 @@
|
||||
./yacc_nop.py:25: Warning. Possible grammar rule 'statement_expr' defined without p_ prefix.
|
||||
yacc: Generating SLR parsing table...
|
||||
67
ext/ply/test/yacc_nop.py
Normal file
67
ext/ply/test/yacc_nop.py
Normal file
@@ -0,0 +1,67 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# yacc_nop.py
|
||||
#
|
||||
# Possible grammar rule defined without p_ prefix
|
||||
# -----------------------------------------------------------------------------
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
from calclex import tokens
|
||||
|
||||
# Parsing rules
|
||||
precedence = (
|
||||
('left','PLUS','MINUS'),
|
||||
('left','TIMES','DIVIDE'),
|
||||
('right','UMINUS'),
|
||||
)
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
def p_statement_assign(t):
|
||||
'statement : NAME EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def statement_expr(t):
|
||||
'statement : expression'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[3] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
def p_error(t):
|
||||
print "Syntax error at '%s'" % t.value
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
|
||||
|
||||
|
||||
4
ext/ply/test/yacc_notfunc.exp
Normal file
4
ext/ply/test/yacc_notfunc.exp
Normal file
@@ -0,0 +1,4 @@
|
||||
yacc: Warning. 'p_statement_assign' not defined as a function
|
||||
yacc: Warning. Token 'EQUALS' defined, but not used.
|
||||
yacc: Warning. There is 1 unused token.
|
||||
yacc: Generating SLR parsing table...
|
||||
65
ext/ply/test/yacc_notfunc.py
Normal file
65
ext/ply/test/yacc_notfunc.py
Normal file
@@ -0,0 +1,65 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# yacc_notfunc.py
|
||||
#
|
||||
# p_rule not defined as a function
|
||||
# -----------------------------------------------------------------------------
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
from calclex import tokens
|
||||
|
||||
# Parsing rules
|
||||
precedence = (
|
||||
('left','PLUS','MINUS'),
|
||||
('left','TIMES','DIVIDE'),
|
||||
('right','UMINUS'),
|
||||
)
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
p_statement_assign = "Blah"
|
||||
|
||||
def p_statement_expr(t):
|
||||
'statement : expression'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[3] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
def p_error(t):
|
||||
print "Syntax error at '%s'" % t.value
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
|
||||
|
||||
|
||||
1
ext/ply/test/yacc_notok.exp
Normal file
1
ext/ply/test/yacc_notok.exp
Normal file
@@ -0,0 +1 @@
|
||||
yacc.YaccError: module does not define a list 'tokens'
|
||||
66
ext/ply/test/yacc_notok.py
Normal file
66
ext/ply/test/yacc_notok.py
Normal file
@@ -0,0 +1,66 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# yacc_notok.py
|
||||
#
|
||||
# A grammar, but we forgot to import the tokens list
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
# Parsing rules
|
||||
precedence = (
|
||||
('left','PLUS','MINUS'),
|
||||
('left','TIMES','DIVIDE'),
|
||||
('right','UMINUS'),
|
||||
)
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
def p_statement_assign(t):
|
||||
'statement : NAME EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement_expr(t):
|
||||
'statement : expression'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[3] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
def p_error(t):
|
||||
print "Syntax error at '%s'" % t.value
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
|
||||
|
||||
|
||||
2
ext/ply/test/yacc_rr.exp
Normal file
2
ext/ply/test/yacc_rr.exp
Normal file
@@ -0,0 +1,2 @@
|
||||
yacc: Generating SLR parsing table...
|
||||
yacc: 1 reduce/reduce conflict
|
||||
71
ext/ply/test/yacc_rr.py
Normal file
71
ext/ply/test/yacc_rr.py
Normal file
@@ -0,0 +1,71 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# yacc_rr.py
|
||||
#
|
||||
# A grammar with a reduce/reduce conflict
|
||||
# -----------------------------------------------------------------------------
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
from calclex import tokens
|
||||
|
||||
# Parsing rules
|
||||
precedence = (
|
||||
('left','PLUS','MINUS'),
|
||||
('left','TIMES','DIVIDE'),
|
||||
('right','UMINUS'),
|
||||
)
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
def p_statement_assign(t):
|
||||
'statement : NAME EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement_assign_2(t):
|
||||
'statement : NAME EQUALS NUMBER'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement_expr(t):
|
||||
'statement : expression'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[3] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
def p_error(t):
|
||||
print "Syntax error at '%s'" % t.value
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
|
||||
|
||||
|
||||
1
ext/ply/test/yacc_simple.exp
Normal file
1
ext/ply/test/yacc_simple.exp
Normal file
@@ -0,0 +1 @@
|
||||
yacc: Generating SLR parsing table...
|
||||
67
ext/ply/test/yacc_simple.py
Normal file
67
ext/ply/test/yacc_simple.py
Normal file
@@ -0,0 +1,67 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# yacc_simple.py
|
||||
#
|
||||
# A simple, properly specifier grammar
|
||||
# -----------------------------------------------------------------------------
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
from calclex import tokens
|
||||
|
||||
# Parsing rules
|
||||
precedence = (
|
||||
('left','PLUS','MINUS'),
|
||||
('left','TIMES','DIVIDE'),
|
||||
('right','UMINUS'),
|
||||
)
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
def p_statement_assign(t):
|
||||
'statement : NAME EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement_expr(t):
|
||||
'statement : expression'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[3] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
def p_error(t):
|
||||
print "Syntax error at '%s'" % t.value
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
|
||||
|
||||
|
||||
2
ext/ply/test/yacc_sr.exp
Normal file
2
ext/ply/test/yacc_sr.exp
Normal file
@@ -0,0 +1,2 @@
|
||||
yacc: Generating SLR parsing table...
|
||||
yacc: 20 shift/reduce conflicts
|
||||
62
ext/ply/test/yacc_sr.py
Normal file
62
ext/ply/test/yacc_sr.py
Normal file
@@ -0,0 +1,62 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# yacc_sr.py
|
||||
#
|
||||
# A grammar with shift-reduce conflicts
|
||||
# -----------------------------------------------------------------------------
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
from calclex import tokens
|
||||
|
||||
# Parsing rules
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
def p_statement_assign(t):
|
||||
'statement : NAME EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement_expr(t):
|
||||
'statement : expression'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[3] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
def p_error(t):
|
||||
print "Syntax error at '%s'" % t.value
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
|
||||
|
||||
|
||||
2
ext/ply/test/yacc_term1.exp
Normal file
2
ext/ply/test/yacc_term1.exp
Normal file
@@ -0,0 +1,2 @@
|
||||
./yacc_term1.py:22: Illegal rule name 'NUMBER'. Already defined as a token.
|
||||
yacc.YaccError: Unable to construct parser.
|
||||
67
ext/ply/test/yacc_term1.py
Normal file
67
ext/ply/test/yacc_term1.py
Normal file
@@ -0,0 +1,67 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# yacc_term1.py
|
||||
#
|
||||
# Terminal used on the left-hand-side
|
||||
# -----------------------------------------------------------------------------
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
from calclex import tokens
|
||||
|
||||
# Parsing rules
|
||||
precedence = (
|
||||
('left','PLUS','MINUS'),
|
||||
('left','TIMES','DIVIDE'),
|
||||
('right','UMINUS'),
|
||||
)
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
def p_statement_assign(t):
|
||||
'NUMBER : NAME EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement_expr(t):
|
||||
'statement : expression'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[3] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
def p_error(t):
|
||||
print "Syntax error at '%s'" % t.value
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
|
||||
|
||||
|
||||
4
ext/ply/test/yacc_unused.exp
Normal file
4
ext/ply/test/yacc_unused.exp
Normal file
@@ -0,0 +1,4 @@
|
||||
./yacc_unused.py:60: Symbol 'COMMA' used, but not defined as a token or a rule.
|
||||
yacc: Symbol 'COMMA' is unreachable.
|
||||
yacc: Symbol 'exprlist' is unreachable.
|
||||
yacc.YaccError: Unable to construct parser.
|
||||
76
ext/ply/test/yacc_unused.py
Normal file
76
ext/ply/test/yacc_unused.py
Normal file
@@ -0,0 +1,76 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# yacc_unused.py
|
||||
#
|
||||
# A grammar with an unused rule
|
||||
# -----------------------------------------------------------------------------
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
from calclex import tokens
|
||||
|
||||
# Parsing rules
|
||||
precedence = (
|
||||
('left','PLUS','MINUS'),
|
||||
('left','TIMES','DIVIDE'),
|
||||
('right','UMINUS'),
|
||||
)
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
def p_statement_assign(t):
|
||||
'statement : NAME EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement_expr(t):
|
||||
'statement : expression'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[3] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
def p_expr_list(t):
|
||||
'exprlist : exprlist COMMA expression'
|
||||
pass
|
||||
|
||||
def p_expr_list_2(t):
|
||||
'exprlist : expression'
|
||||
pass
|
||||
|
||||
|
||||
def p_error(t):
|
||||
print "Syntax error at '%s'" % t.value
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
|
||||
|
||||
|
||||
2
ext/ply/test/yacc_uprec.exp
Normal file
2
ext/ply/test/yacc_uprec.exp
Normal file
@@ -0,0 +1,2 @@
|
||||
./yacc_uprec.py:35: Nothing known about the precedence of 'UMINUS'
|
||||
yacc.YaccError: Unable to construct parser.
|
||||
62
ext/ply/test/yacc_uprec.py
Normal file
62
ext/ply/test/yacc_uprec.py
Normal file
@@ -0,0 +1,62 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# yacc_uprec.py
|
||||
#
|
||||
# A grammar with a bad %prec specifier
|
||||
# -----------------------------------------------------------------------------
|
||||
import sys
|
||||
sys.tracebacklimit = 0
|
||||
|
||||
from calclex import tokens
|
||||
|
||||
# Parsing rules
|
||||
|
||||
# dictionary of names
|
||||
names = { }
|
||||
|
||||
def p_statement_assign(t):
|
||||
'statement : NAME EQUALS expression'
|
||||
names[t[1]] = t[3]
|
||||
|
||||
def p_statement_expr(t):
|
||||
'statement : expression'
|
||||
print t[1]
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression PLUS expression
|
||||
| expression MINUS expression
|
||||
| expression TIMES expression
|
||||
| expression DIVIDE expression'''
|
||||
if t[2] == '+' : t[0] = t[1] + t[3]
|
||||
elif t[2] == '-': t[0] = t[1] - t[3]
|
||||
elif t[2] == '*': t[0] = t[1] * t[3]
|
||||
elif t[3] == '/': t[0] = t[1] / t[3]
|
||||
|
||||
def p_expression_uminus(t):
|
||||
'expression : MINUS expression %prec UMINUS'
|
||||
t[0] = -t[2]
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
try:
|
||||
t[0] = names[t[1]]
|
||||
except LookupError:
|
||||
print "Undefined name '%s'" % t[1]
|
||||
t[0] = 0
|
||||
|
||||
def p_error(t):
|
||||
print "Syntax error at '%s'" % t.value
|
||||
|
||||
import yacc
|
||||
yacc.yacc()
|
||||
|
||||
|
||||
|
||||
|
||||
1846
ext/ply/yacc.py
Normal file
1846
ext/ply/yacc.py
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user