Name: Anonymous 2010-11-30 17:46
I want to made a simple programming language, what should I use for parsing:
1. lex + yacc
2. lemon
3. parsec
4. other (what?)
1. lex + yacc
2. lemon
3. parsec
4. other (what?)
digit x -> x.{\0=>0;\1=>1;\2=>2;\3=>3;\4=>4;\5=>5;\6=>6;\7=>7;\8=>8;\9=>9}
number [@xs] -> {r [] => r; r [(x:!digit)@xs] => rec 10r+x xs} 0 xs
op [x] -> x.{\+ => '`+`; \- => '`-`; \* => '`*`; \/ => '`/`}
term x -> x.{[\( @(a:!expr) \)] => [a]; [@(a:!number)] => a}
expr x -> x.{[@(a:!term)] => a; [@(a:!term) @(o:!op) @(b:!expr)] => [o a b]}
strip p l -> l.{x=>x; [@xs !p @ys]=>[@xs @(rec ys)]}
parse string -> string.asList.(strip \Space ?).expr
Lsb2 -> 0
parseLsb2 [a b] -> b<<8 + a
breakLsb2 x -> [mod,x,256 mod,x>>8,256]
setSizeof Lsb2 2
Lsb4 -> 0
parseLsb4 [a b c d] -> d<<24 + c<<16 + b<<8 + a
breakLsb4 x -> [mod,x ,256 mod,x>> 8,256
mod,x>>16,256 mod,x>>24,256]
setSizeof Lsb4 4
ElfId -> []
parseElfId x -> x when x.len==16
breakElfId x -> x
setSizeof ElfId 16
ElfType -> gElfTypes|0
parseElfType x -> if v:x.parseLsb2 (fnd {[!v _ _]} gElfTypes) || #($x UNKNOWN "Unknown")
breakElfType [x _ _] -> x.breakLsb
setSizeof ElfType 2
machineInfo x -> (fnd [id _ _]~>id==x gMachines) ||
#(RESERVED $x UNKNOWN "Unknown")
ElfMachineId -> gMachines|0
parseElfMachineId x -> v.machineInfo when v:x.parseLsb2
breakElfMachineId [x _ _] -> x.breakLsb2
setSizeof ElfMachineId 2
class ElfHeader
elfId = ElfId // processor independent header part
type = ElfType
machine = ElfMachineId
version = Lsb4 // file format version
entry = Lsb4 // entry into program or null, if file has no entry point
phoff = Lsb4 // program header table offset
shoff = Lsb4 // section header table offset
flags = Lsb4
ehsize = Lsb2 // size of this ElfHeader
phentsize = Lsb2 // program header table: entry size
phnum = Lsb2 // program header table: number of entries
shentsize = Lsb2 // section header table: entry size
shnum = Lsb2 // section header table: number of entries
shstrndx = Lsb2 // string table section index or SHN_UNDEF
class Elf header segments sections strings data
loadElfHeader file -> file.fget.asList |>
{ default => error "not an ELF: $file"
f:[127 69 76 70 @_] => f} |>
{data:[@(hdr:!parseElfHeader) @rest] => (Elf header=hdr data=data)}
gMachines =: (ltl '{
//Id Symbol Description
0 EM_NONE "No machine"
1 EM_M32 "AT&T WE 32100"
2 EM_SPARC "SPARC"
3 EM_386 "Intel 80386"
4 EM_68K "Motorola 68000"
5 EM_88K "Motorola 88000"
7 EM_860 "Intel 80860"
8 EM_MIPS "MIPS I Architecture"
10 EM_MIPS_RS3_LE "MIPS RS3000 Little-endian"
15 EM_PARISC "Hewlett-Packard PA-RISC"
17 EM_VPP500 "Fujitsu VPP500"
18 EM_SPARC32PLUS "Enhanced instruction set SPARC"
19 EM_960 "Intel 80960"
20 EM_PPC "Power PC"
36 EM_V800 "NEC V800"
37 EM_FR20 "Fujitsu FR20"
38 EM_RH32 "TRW RH-32"
39 EM_RCE "Motorola RCE"
40 EM_ARM "Advanced RISC Machines ARM"
41 EM_ALPHA "Digital Alpha"
42 EM_SH "Hitachi SH"
43 EM_SPARCV9 "SPARC Version 9"
44 EM_TRICORE "Siemens Tricore embedded processor"
45 EM_ARC "Argonaut RISC Core, Argonaut Technologies Inc."
46 EM_H8_300 "Hitachi H8/300"
47 EM_H8_300H "Hitachi H8/300H"
48 EM_H8S "Hitachi H8S"
49 EM_H8_500 "Hitachi H8/500"
50 EM_IA_64 "Intel MercedTM Processor"
51 EM_MIPS_X "Stanford MIPS-X"
52 EM_COLDFIRE "Motorola Coldfire"
53 EM_68HC12 "Motorola M68HC12"
})
m:times head @body ->
$@(do c:head.{_=>gensym; #(`:` $c $n)=>c}
n:head.{x=>x ; #(`:` $c $n)=>n}
#(&e:$n {$c => if $c!=&e do $body rec,$c+1} 0))
// Usage: times i:10 say i