source: proto/charsetcompiler/charset_compiler.py @ 1052

Last change on this file since 1052 was 1052, checked in by cameron, 8 years ago

Update code generation for Pablo

File size: 22.1 KB
Line 
1# -*- coding: utf-8 -*-
2#
3#  Character Class Compiler
4#
5#  Version 0.7 - August 14, 2009
6#     Adding generation of Python code;  parabix 2 definitions
7#  Copyright (c) 2007, Robert D. Cameron
8#  All rights reserved.
9#
10#  TO DO Notes
11#
12#  1.  Perhaps the character set definition should be extended to
13#      allow other set operations.   For example, the 'Restricted' set
14#      of XML might be defined as ['\x00-\x1f'] - ['\x09', '\x0a', '\x0d']
15#      This would require fewer operations to compute.
16#
17#  2.  The range logic generator should be modified to group
18#      bit variables the same way as the individual character logic
19#      generator (i.e., combining bits 0 and 1, 2 and 3, 4 and 5 and
20#      6 and 7 first.
21#
22#  3.  Extend for 16-bit and full Unicode character values.
23#
24#
25#--------------------------------------------------------------------------
26#
27#  Data types
28#  1. Character Set Definitions
29#  2. Boolean Expressions
30#  3. Code Generator Objects
31#
32import sys
33import re, binascii, string
34
35import charset_def
36CharDef = charset_def.CharDef
37CharSetDef = charset_def.CharSetDef
38
39import charsets
40DefinitionSet = charsets.DefinitionSet
41
42import charset_input_parser
43
44#
45# Symbolic Representations of Boolean Expressions
46#
47
48class BoolExpr:
49   """The BoolExpr class and its subclasses provide a symbolic
50      representation of Boolean expressions.
51   """
52   pass
53
54class Var(BoolExpr):
55    def __init__(self, varname):
56        self.varname = varname
57    def show(self): return 'Var("' + self.varname + '")'
58
59class TrueLiteral(BoolExpr):
60    def __init__(self):
61        self.value = True
62    def show(self): return 'T'
63
64class FalseLiteral(BoolExpr):
65    def __init__(self):
66        self.value = False
67    def show(self): return 'F'
68
69class Not(BoolExpr):
70    def __init__(self, expr):
71        self.operand = expr
72    def show(self): return 'Not(%s)' % (self.operand.show())
73
74class And(BoolExpr):
75    def __init__(self, expr1, expr2):
76        self.operand1 = expr1
77        self.operand2 = expr2
78    def show(self): return 'And(%s, %s)' % (self.operand1.show(), self.operand2.show())
79
80class Or(BoolExpr):
81    def __init__(self, expr1, expr2):
82        self.operand1 = expr1
83        self.operand2 = expr2
84    def show(self): return 'Or(%s, %s)' % (self.operand1.show(), self.operand2.show())
85
86class Xor(BoolExpr):
87    def __init__(self, expr1, expr2):
88        self.operand1 = expr1
89        self.operand2 = expr2
90    def show(self): return 'Xor(%s, %s)' % (self.operand1.show(), self.operand2.show())
91
92class Sel(BoolExpr):
93    def __init__(self, expr1, expr2, expr3):
94        self.sel = expr1
95        self.true_branch = expr2
96        self.false_branch = expr3
97    def show(self): return 'Sel(%s, %s, %s)' % (self.sel.show(), self.true_branch.show(), self.false_branch.show())
98
99
100#
101# Optimizing Constructors for Boolean Expressions
102# - Maintaining Assembler Instruction Form:
103#   - All boolean algebraic rules involving true/false applied.
104#   - Negations restricted:
105#       - no negations within or (DeMorgan's to nand)
106#       - at most one negation within and
107#
108
109def make_not(expr):
110    if isinstance(expr, TrueLiteral):
111        return FalseLiteral()
112    elif isinstance(expr, FalseLiteral):
113        return TrueLiteral()
114    elif isinstance(expr, Not):
115        return expr.operand
116    else: return Not(expr)
117
118def make_and(expr1, expr2):
119    if isinstance(expr1, TrueLiteral):
120        return expr2
121    elif isinstance(expr2, TrueLiteral):
122        return expr1
123    elif isinstance(expr1, FalseLiteral):
124        return FalseLiteral()
125    elif isinstance(expr2, FalseLiteral):
126        return FalseLiteral()
127    elif equal_exprs(expr1, expr2): return expr1
128    elif isinstance(expr1, Not):
129        if isinstance(expr2, Not):
130            return make_not(make_or(expr1.operand, expr2.operand))
131        elif equal_exprs(expr1.operand, expr2): return FalseLiteral()
132        else: return And(expr1, expr2)
133    elif isinstance(expr2, Not):
134        if equal_exprs(expr1, expr2.operand): return FalseLiteral()
135        else: return And(expr1, expr2)
136    else: return And(expr1, expr2)
137
138def make_or(expr1, expr2):
139    if isinstance(expr1, FalseLiteral):
140        return expr2
141    elif isinstance(expr2, FalseLiteral):
142        return expr1
143    elif isinstance(expr1, TrueLiteral):
144        return TrueLiteral()
145    elif isinstance(expr2, TrueLiteral):
146        return TrueLiteral()
147    elif isinstance(expr1, Not):
148        return make_not(make_and(expr1.operand, make_not(expr2)))
149    elif isinstance(expr2, Not):
150        return make_not(make_and(make_not(expr1), expr2.operand))
151    elif equal_exprs(expr1, expr2): return expr1
152    elif isinstance(expr1, And) and isinstance(expr2, And):
153        # These optimizations factor out common components that
154        # can occur when sets are formed by union (e.g., union of
155        # [a-z] and [A-Z].
156        if equal_exprs(expr1.operand1, expr2.operand1):
157            return make_and(expr1.operand1, make_or(expr1.operand2, expr2.operand2))
158        elif equal_exprs(expr1.operand2, expr2.operand2):
159            return make_and(expr1.operand2, make_or(expr1.operand1, expr2.operand1))
160        elif equal_exprs(expr1.operand1, expr2.operand2):
161            return make_and(expr1.operand1, make_or(expr1.operand2, expr2.operand1))
162        elif equal_exprs(expr1.operand2, expr2.operand1):
163            return make_and(expr1.operand2, make_or(expr1.operand1, expr2.operand2))
164        else: return Or(expr1, expr2)
165    else: return Or(expr1, expr2)
166
167def make_sel(if_expr, T_expr, F_expr):
168    if isinstance(if_expr, TrueLiteral):
169        return T_expr
170    elif isinstance(if_expr, FalseLiteral):
171        return F_expr
172    elif isinstance(T_expr, TrueLiteral):
173        # if x then T else y = x or y
174        return make_or(if_expr, F_expr) 
175    elif isinstance(T_expr, FalseLiteral):
176        # if x then F else y = not(x) and y
177        return make_and(make_not(if_expr), F_expr) 
178    elif isinstance(F_expr, FalseLiteral):
179        # if x then y else F = x and y
180        return make_and(if_expr, T_expr) 
181    elif isinstance(F_expr, TrueLiteral):
182        # if x then y else T = not(x) or y
183        return make_or(make_not(if_expr), T_expr)
184    elif equal_exprs(T_expr, F_expr):
185        return T_expr
186    else: return Sel(if_expr, T_expr, F_expr)
187
188
189def make_xor(expr1, expr2):
190    if isinstance(expr1, FalseLiteral):
191        return expr2
192    elif isinstance(expr1, FalseLiteral):
193        return expr1
194    elif isinstance(expr1, TrueLiteral):
195        return make_not(expr2)
196    elif isinstance(expr2, TrueLiteral):
197        return make_not(expr1)
198    elif isinstance(expr1, Not) and isinstance(expr2, Not):
199        return make_xor(expr1.operand, expr2.operand)
200    else: return Xor(expr1, expr2)
201
202def equal_exprs(e1, e2):
203    if isinstance(e1, FalseLiteral): return isinstance(e2, FalseLiteral)
204    elif isinstance(e1, TrueLiteral): return isinstance(e2, TrueLiteral)
205    elif isinstance(e1, Var) and isinstance(e2, Var):
206        return e1.varname == e2.varname
207    elif isinstance(e1, Not) and isinstance(e2, Not):
208        return equal_exprs(e1.operand, e2.operand)
209    elif isinstance(e1, And) and isinstance(e2, And):
210        if equal_exprs(e1.operand1, e2.operand1):
211            return equal_exprs(e1.operand2, e2.operand2)
212        elif equal_exprs(e1.operand1, e2.operand2):
213            return equal_exprs(e1.operand2, e2.operand1)
214        else: return False
215    elif isinstance(e1, Or) and isinstance(e2, Or):
216        if equal_exprs(e1.operand1, e2.operand1):
217            return equal_exprs(e1.operand2, e2.operand2)
218        elif equal_exprs(e1.operand1, e2.operand2):
219            return equal_exprs(e1.operand2, e2.operand1)
220        else: return False
221    elif isinstance(e1, Xor) and isinstance(e2, Xor):
222        if equal_exprs(e1.operand1, e2.operand1):
223            return equal_exprs(e1.operand2, e2.operand2)
224        elif equal_exprs(e1.operand1, e2.operand2):
225            return equal_exprs(e1.operand2, e2.operand1)
226        else: return False
227    elif isinstance(e1, Sel) and isinstance(e2, Sel):
228        if equal_exprs(e1.sel, e2.sel):
229             if equal_exprs(e1.true_branch, e2.true_branch):
230                 return equal_exprs(e1.false_branch, e2.false_branch)
231             else: return False
232        else: return False
233
234
235#
236#
237#  Boolean Expressions for Character Class Definitions
238#
239
240def bit_var(n):
241#    return 'bit[%i]' % n
242    return 'basis_bits.bit_%i' % n
243def make_bitv(n):
244    return Var(bit_var(n))
245
246# Deprecated
247def make_2bit_test(var1, var2, bit_pattern):
248  if bit_pattern == 0: 
249    return make_not(make_or(var1, var2))
250  elif bit_pattern == 1:
251    return make_and(make_not(var1), var2)
252  elif bit_pattern == 2:
253    return make_and(var1, make_not(var2))
254  else: return make_and(var1, var2)
255
256# Deprecated
257def make_8bit_test(bit_pattern):
258  return make_and(make_and(make_2bit_test(make_bitv(0), make_bitv(1), (bit_pattern >> 6) & 3),
259                           make_2bit_test(make_bitv(2), make_bitv(3), (bit_pattern >> 4) & 3)),
260                  make_and(make_2bit_test(make_bitv(4), make_bitv(5), (bit_pattern >> 2) & 3),
261                           make_2bit_test(make_bitv(6), make_bitv(7), (bit_pattern) & 3)))
262
263
264def make_bit_test(pattern, bit_count):
265    bit_terms = []
266    test_bit = 2**(bit_count - 1)
267    for i in range(0, bit_count):
268        if (pattern & test_bit) == 0:
269            bit_terms.append(make_not(make_bitv(i)))
270        else: bit_terms.append(make_bitv(i))
271        test_bit >>= 1
272    while len(bit_terms) > 1:
273        new_terms = []
274        for i in range(0, len(bit_terms)/ 2):
275            new_terms.append(make_and(bit_terms[2*i], bit_terms[2*i+1]))
276        if len(bit_terms) % 2 == 1:
277            new_terms.append(bit_terms[-1])
278        bit_terms = new_terms
279    return bit_terms[0]
280
281
282def char_test_expr(ch):
283    return make_bit_test(ord(ch), 8)
284    #return make_8bit_test(ord(ch))
285
286def GE_Range(N, n):
287    if N == 0: return TrueLiteral()
288    elif N % 2 == 0 and (n >> (N - 2)) == 0:
289        return make_or(make_or(make_bitv(8-N), make_bitv(9-N)),
290                        GE_Range(N - 2, n))
291    elif N % 2 == 0 and (n >> (N - 2)) == 3:   # >= 11xxxx
292        return make_and(make_and(make_bitv(8-N), make_bitv(9-N)),
293                        GE_Range(N - 2, n - (3 << (N-2))))
294    elif N >= 1:
295        hi_bit = n & (1 << (N-1))
296        lo_bits = n - hi_bit
297        lo_range = GE_Range(N-1, lo_bits)
298        if hi_bit == 0:
299            # If the hi_bit of n is not set, then whenever the corresponding bit
300            # is set in the target, the target will certainly be >=.  Otherwise,
301            # the value of GE_range(N-1, lo_bits) is required.
302            return make_or(make_bitv(8-N), lo_range)
303        else: 
304            # If the hi_bit of n is set, then the corresponding bit must be set
305            # in the target for >= and GE_range(N-1, lo_bits) must also be true.
306            return make_and(make_bitv(8-N), lo_range)
307
308def LE_Range(N, n):
309    # If an N-bit pattern is all ones, then it is always
310    # true that any n-bit value is LE this pattern.
311    # Handling this as a special case avoids an overflow
312    # issue with n+1 requiring more than N bits.
313    if n+1 == 2 ** N:
314        return TrueLiteral()
315    else:
316        return make_not(GE_Range(N, n+1))
317
318BadRange = Exception()
319
320
321def Make_Range(n1, n2):  # require n2 >= n1
322    diff_bits = n1 ^ n2
323    diff_count = 0
324    while diff_bits > 0:
325        diff_count += 1
326        diff_bits >>= 1
327    if n2 < n1 or diff_count > 8: raise BadRange()
328    common = make_bit_test(n1 >> diff_count, 8 - diff_count)
329    if diff_count == 0: return common
330    mask = 2**(diff_count-1) - 1
331    lo_test = GE_Range(diff_count-1, n1 & mask)
332    hi_test = LE_Range(diff_count-1, n2 & mask)
333    return make_and(common, make_sel(make_bitv(8-diff_count), hi_test, lo_test))
334
335# Deprecated   
336def Inclusive_Range(N, n1, n2):  # require n2 >= n1
337    if N == 0: return TrueLiteral()
338    elif n1 >= 2**(N-1):
339        return make_and(make_bitv(8-N), Inclusive_Range(N-1, n1 - 2**(N-1), n2 - 2**(N-1)))
340    elif n2 < 2**(N-1):
341        return make_and(make_not(make_bitv(8-N)), Inclusive_Range(N-1, n1, n2))
342    else:
343        n2_lo = n2 - 2**(N-1)
344        lo_test = GE_Range(N-1, n1)
345        hi_test = LE_Range(N-1, n2_lo)
346        # special optimization?
347        # if n2_lo + 1 == n1: return make_xor(make_bit_test(8-N), lo_test)
348        return make_sel(make_bitv(8-N), lo_test, hi_test)
349
350BadCharSetItem = Exception()
351
352def char_or_range_expr(charset_item):
353    if len(charset_item) == 1:
354        return char_test_expr(charset_item[0])
355    elif len(charset_item) == 3:
356        if charset_item[1] == '-' and ord(charset_item[0]) <= ord(charset_item[2]):
357             return Make_Range(ord(charset_item[0]), ord(charset_item[2]))
358             #  return Inclusive_Range(8, ord(charset_item[0]), ord(charset_item[2]))
359    print charset_item
360    raise BadCharSetItem
361
362def charset_expr(chardef):
363    e1 = char_or_range_expr(chardef.items[0])
364    for i in range(1, len(chardef.items)):
365        e1 = make_or(e1, char_or_range_expr(chardef.items[i]))
366    if chardef.complemented: return make_not(e1)
367    else: return e1
368
369#
370#
371#  Code Generation
372#
373class CodeGenObject:
374    def __init__(self, predeclared, typedecl='BitBlock '):
375        self.gensym_template = 'temp%i'
376        self.gensym_counter = 0
377        self.generated_code = []
378        self.common_expression_map = {}
379        for sym in predeclared: self.common_expression_map[sym] = sym
380        self.typedecl = typedecl
381    def add_assignment(self, varname, expr):
382        self.common_expression_map[expr] = varname
383        #self.generated_code.append('%s%s = %s;\n' % (self.typedecl, varname, expr))
384        self.generated_code.append('\t%s%s = %s\n' % (self.typedecl, varname, expr))
385    def expr_string_to_variable(self, expr_string):
386        if self.common_expression_map.has_key(expr_string): 
387            return self.common_expression_map[expr_string]
388        else:
389            self.gensym_counter += 1
390            sym = self.gensym_template % self.gensym_counter
391            self.add_assignment(sym, expr_string)
392            return sym
393    def showcode(self):
394        s = ''
395        for stmt in self.generated_code: s += stmt
396        return s
397
398def expr2simd(genobj, expr):
399    """Translate a Boolean expression into three-address Altivec code
400       using code generator object genobj.
401    """
402    if isinstance(expr, TrueLiteral): return 'simd_const_1(1)'
403    elif isinstance(expr, FalseLiteral): return 'simd_const_1(0)'
404    elif isinstance(expr, Var): return expr.varname
405    elif isinstance(expr, Not):
406       e = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand))
407       return 'simd_andc(simd_const_1(1), %s)' % (e)
408    elif isinstance(expr, Or):
409       e1 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand1))
410       e2 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand2))
411       return 'simd_or(%s, %s)' % (e1, e2)
412    elif isinstance(expr, Xor):
413       e1 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand1))
414       e2 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand2))
415       return 'simd_xor(%s, %s)' % (e1, e2)
416    elif isinstance(expr, And):
417       if isinstance(expr.operand1, Not):
418           e1 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand1.operand))
419           e2 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand2))
420           return 'simd_andc(%s, %s)' % (e2, e1)
421       elif isinstance(expr.operand2, Not):
422           e1 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand1))
423           e2 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand2.operand))
424           return 'simd_andc(%s, %s)' % (e1, e2)
425       else:
426           e1 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand1))
427           e2 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand2))
428           return 'simd_and(%s, %s)' % (e1, e2)
429    elif isinstance(expr, Sel):
430       sel = genobj.expr_string_to_variable(expr2simd(genobj, expr.sel))
431       e1 = genobj.expr_string_to_variable(expr2simd(genobj, expr.true_branch))
432       e2 = genobj.expr_string_to_variable(expr2simd(genobj, expr.false_branch))
433       return 'simd_if(%s, %s, %s)' %(sel, e1, e2)
434
435def chardef2simd(genobj, chardef):
436    genobj.add_assignment(chardef.name, expr2simd(genobj, charset_expr(chardef)))
437
438def chardeflist2simd(chardeflist):
439    cgo = CodeGenObject([bit_var(i) for i in range(0,8)])
440    for d in chardeflist:
441        chardef2simd(cgo, d)
442    return cgo.showcode()
443
444def expr2py(genobj, expr):
445    """Translate a Boolean expression into three-address python code
446       using code generator object genobj.
447    """
448    if isinstance(expr, TrueLiteral): return '-1'
449    elif isinstance(expr, FalseLiteral): return '0'
450    elif isinstance(expr, Var): return expr.varname
451    elif isinstance(expr, Not):
452       e = genobj.expr_string_to_variable(expr2py(genobj, expr.operand))
453       return '(~%s)' % (e)
454    elif isinstance(expr, Or):
455       e1 = genobj.expr_string_to_variable(expr2py(genobj, expr.operand1))
456       e2 = genobj.expr_string_to_variable(expr2py(genobj, expr.operand2))
457       return '(%s | %s)' % (e1, e2)
458    elif isinstance(expr, Xor):
459       e1 = genobj.expr_string_to_variable(expr2py(genobj, expr.operand1))
460       e2 = genobj.expr_string_to_variable(expr2py(genobj, expr.operand2))
461       return '(%s ^ %s)' % (e1, e2)
462    elif isinstance(expr, And):
463       if isinstance(expr.operand1, Not):
464           e1 = genobj.expr_string_to_variable(expr2py(genobj, expr.operand1.operand))
465           e2 = genobj.expr_string_to_variable(expr2py(genobj, expr.operand2))
466           return '(%s &~ %s)' % (e2, e1)
467       elif isinstance(expr.operand2, Not):
468           e1 = genobj.expr_string_to_variable(expr2py(genobj, expr.operand1))
469           e2 = genobj.expr_string_to_variable(expr2py(genobj, expr.operand2.operand))
470           return '(%s &~ %s)' % (e1, e2)
471       else:
472           e1 = genobj.expr_string_to_variable(expr2py(genobj, expr.operand1))
473           e2 = genobj.expr_string_to_variable(expr2py(genobj, expr.operand2))
474           return '(%s & %s)' % (e1, e2)
475    elif isinstance(expr, Sel):
476       sel = genobj.expr_string_to_variable(expr2py(genobj, expr.sel))
477       e1 = genobj.expr_string_to_variable(expr2py(genobj, expr.true_branch))
478       e2 = genobj.expr_string_to_variable(expr2py(genobj, expr.false_branch))
479       return '((%s & %s)|(~(%s) & %s))' %(sel, e1, sel, e2)
480
481def chardef2py(genobj, chardef):
482    genobj.add_assignment(chardef.name, expr2py(genobj, charset_expr(chardef)))
483
484
485def py_chardefmap(chardeflist):
486    defs = ["'%s' : %s" % (d.name,d.name) for d in chardeflist]
487    return  '{%s}' % string.join(defs, ',\n\t')
488
489def chardeflist2py(chardeflist):
490    cgo = CodeGenObject([bit_var(i) for i in range(0,8)],'')
491    for d in chardeflist:
492        chardef2py(cgo, d) 
493    return cgo.showcode()# + "  return "+ py_chardefmap(chardeflist) + "\n"
494
495
496def code_gen_for_transcode(transcode_tbl_h, transcode_tbl_l):
497  cgo = CodeGenObject([bit_var(i) for i in range(0,8)])
498  xor_tbl_l = [transcode_tbl_l[code] ^ code for code in range(256)]
499  code_gen_for_transcode_8bit(cgo, "x16h", transcode_tbl_h)
500  code_gen_for_transcode_8bit(cgo, "x16l", xor_tbl_l)
501  return cgo.showcode()
502
503def code_gen_for_transcode_8bit(cgo, pfx, tbl):
504  for bit in range(8):
505    bit_mask = 256 >> bit
506    in_run = False
507    first_expr_found = False
508    bit_expr = FalseLiteral()
509    for code in range(256):
510      if tbl[code] & bit_mask != 0:
511        if not in_run:
512          in_run = True
513          run_start = code
514      else:
515        if in_run:
516          if run_start == code-1:
517            e1 = char_test_expr(chr(code - 1))
518          else:
519            e1 = Make_Range(run_start, code - 1)
520          if first_expr_found:
521            bit_expr = make_or(bit_expr, e1)
522          else:
523            first_expr_found = True
524            bit_expr = e1
525    if first_expr_found:
526      cgo.add_assignment("%s[%i]" % (pfx, bit), expr2simd(cgo, bit_expr))
527
528# Work with tables from
529# /home/cameron/glibc-2.3.5/localedata/charmaps/
530
531charmap_line_RE = re.compile("<U([0-9A-F][0-9A-F])([0-9A-Z][0-9A-Z])>\s+/x([0-9a-f][0-9a-f])\s")
532
533def read_char_map(file):
534  f = open(file)
535  lines = f.readlines()
536  matches = [charmap_line_RE.match(l) for l in lines]
537  u16hi = [ord(binascii.unhexlify(m.group(1))) for m in matches if m]
538  u16lo = [ord(binascii.unhexlify(m.group(2))) for m in matches if m]
539  codes = [ord(binascii.unhexlify(m.group(3))) for m in matches if m]
540  codes_OK = [c for c in range(256) if codes[c] == c]
541  if len(codes_OK) != 256:
542    print("Code map failure reading %s" % file)
543  return (u16hi, u16lo)
544
545import codecs
546def ascii2ebcdic_chardeflist(defs):
547        encoder = codecs.getencoder('cp037')
548        return [xlate_chardef(d, encoder) for d in defs]
549
550def xlate_char_or_range(charset_item, encoder):
551    if len(charset_item) == 1:
552        return encoder(charset_item[0])
553    elif len(charset_item) == 3:
554        if charset_item[1] == '-' and ord(charset_item[0]) <= ord(charset_item[2]):
555             return Make_Range(ord(charset_item[0]), ord(charset_item[2]))
556             #  return Inclusive_Range(8, ord(charset_item[0]), ord(charset_item[2]))
557    print charset_item
558    raise BadCharSetItem
559       
560def xlate_chardef(chardef, encoder):
561  if isinstance(chardef, CharDef):
562    return CharDef(chardef.name, encoder(chardef.items[0])[0], chardef.complemented)
563  else:
564    cdefs = []
565    for item in chardef.items:
566        if len(item) == 1: cdefs.append(encoder(item)[0])
567        elif len(item) == 3:
568          for v in range(ord(item[0]), ord(item[-1])+1):
569            cdefs.append(encoder(chr(v))[0])
570        else: raise BadCharSetItem
571    return CharSetDef(chardef.name, cdefs, chardef.complemented)
572
573def main():
574    if len(sys.argv) == 2:
575        # if the specified argument is not in the DefinitionSet, then assume that it's a filename
576        if sys.argv[1] not in DefinitionSet:
577            #define the characters in the list
578            defs = charset_input_parser.input_chardef(sys.argv[1])
579                                               
580            #print chardeflist2simd(defs)
581            print chardeflist2py(defs)
582        else:
583            #print chardeflist2simd(DefinitionSet[sys.argv[1]])
584            print chardeflist2py(DefinitionSet[sys.argv[1]])
585    elif len(sys.argv) == 3 and sys.argv[2] == 'EBCDIC':
586        defs = ascii2ebcdic_chardeflist(DefinitionSet[sys.argv[1]])
587        print chardeflist2simd(defs)
588    else:
589        print "Usage python charset_compiler.py <name> [EBCDIC]"
590        for k in DefinitionSet.keys(): print k
591
592if __name__ == "__main__": main()
Note: See TracBrowser for help on using the repository browser.