############################################################################ # # File: hufftab.icn # # Subject: Program to compute Huffman state transitions # # Author: Gregg M. Townsend # # Date: November 14, 1994 # ############################################################################ # # This file is in the public domain. # ############################################################################ # # Each input line should be a string of 0s & 1s followed by a value # field. Output is a list of items in a form suitable for inclusion # by a C program as initialization for an array. Each pair of items # indicates the action to be taken on receipt of a 0 or 1 bit from the # corresponding state; this is either a state number if more decoding # is needed or the value field from the input if not. State 0 is the # initial state; 0 is output only for undefined states. States are # numbered by two to facilitate use of a one-dimensional array. # # sample input: corresponding output: # 00 a /* 0 */ 2, c, a, 4, 0, b, # 011 b # 1 c [new line started every 10 entries] # # Interpretation: # from state 0, input=0 => go to state 2, input=1 => return c # from state 2, input=0 => return a, input=1 => go to state 4 # from state 4, input=0 => undefined, input=1 => return b # ############################################################################ global curstate, sttab, line procedure main() local code, val, n sttab := list() put(sttab) put(sttab) while line := read() do { line ? { if ="#" | pos(0) then next (code := tab(many('01'))) | (write(&errout, "bad: ", line) & next) tab(many(' \t')) val := tab(0) } curstate := 1 every bit(!code[1:-1]) curstate +:= code[-1] if \sttab[curstate] then write(&errout, "dupl: ", line) sttab[curstate] := val } write("/* generated by machine -- do not edit! */") write() writes("/* 0 */") out(sttab[1]) every n := 2 to *sttab do { if n % 10 = 1 then writes("\n/* ", n-1, " */") out(sttab[n]) } write() end procedure bit(c) curstate +:= c if integer(sttab[curstate]) then { curstate := sttab[curstate] return } if type(sttab[curstate]) == "string" then write(&errout, "dupl: ", line) curstate := sttab[curstate] := *sttab + 1 put(sttab) put(sttab) end procedure out(v) if type(v) == "integer" then writes(right(v-1, 6), ",") else writes(right(\v | "0", 6), ",") end