context number context unsigned literal `true `false token OCT / '0'[0-7]+ / token DEC / [0-9]+ / token HEX / '0x' xdigit+ / int strtoull(a:str, b:int) = c_strtoull def type value:int [`false] { lhs.value = 0 } | [`true] { lhs.value = 1 } | [OCT] { lhs.value = strtoull($r1, 8) } | [DEC] { lhs.value = strtoull($r1, 10) } | [HEX] { lhs.value = strtoull($r1, 16) } end lex ignore / space+ / literal `+ `- end def type value:int [unsigned::type] { lhs.value = r1.value } | [`- type] { lhs.value = r2.value - (r2.value * 2) } | [`+ type] { lhs.value = r2.value } end context string rl ESC / '\\' / token ESC_CHR / ESC [abfnrtv\\'"e] / token ESC_HEX / ESC 'x' xdigit{2} / token ESC_OCT / ESC [0-7]{1,3} / token CHAR / ^cntrl - ['"] - ESC / literal `' `" def raw [ESC_CHR] # TODO: how to output raw bytes? | [ESC_HEX] # TODO: how to output raw bytes? | [ESC_OCT] # TODO: how to output raw bytes? | [CHAR] def type length:int [`' raw:raw* `'] { i:int = 0 for s:raw in r2 i = i + 1 lhs.length = i } | [`" raw:raw* `"] { i:int = 0 for s:raw in r2 i = i + 1 lhs.length = i } end context name token NAME / [a-zA-Z_][a-zA-Z_0-9]* / def type [NAME] end