source: proto/charsetcompiler/generate_UCD_tests.py @ 4457

Last change on this file since 4457 was 4457, checked in by cameron, 4 years ago

Generate Unicode Level 1 property tests

File size: 7.6 KB
Line 
1#
2# generate_UCD_tests.py -
3# generating Python pablo functions for various Unicode properties
4#
5# Robert D. Cameron
6# January 31, 2015
7#
8# Licensed under Open Software License 3.0.
9#
10#
11import re, string, os.path, UCD.cformat
12from random import randint
13from UCD.unicode_set import *
14from UCD.UCD_parser import *
15from if_hierarchy import *
16from string import Template
17
18class UCD_test_generator():
19    def __init__(self): 
20        self.enum_value_map = {}
21        self.binary_value_map = {}
22        self.all_good_set = uset_union(range_uset(0x20, 0xD7FF), range_uset(0xE000,0x10FFFF))
23        self.all_good_set = uset_difference(self.all_good_set, singleton_uset(0x85))
24        self.all_good_set = uset_difference(self.all_good_set, range_uset(0x2028,0x2029))
25
26    def load_property_name_info(self):
27        (self.property_enum_name_list, self.full_name_map, self.property_lookup_map, self.property_kind_map) = parse_PropertyAlias_txt()
28
29    def load_property_value_info(self):
30        (self.property_value_list, self.property_value_enum_integer, self.property_value_full_name_map, self.property_value_lookup_map, self.missing_specs) = parse_PropertyValueAlias_txt(self.property_lookup_map)
31
32    def load_enumerated_property_data(self, filename_root, property_code):
33        vlist = self.property_value_list[property_code]
34        canon_map = self.property_value_lookup_map[property_code]
35        (prop_values, value_map) = parse_UCD_enumerated_property_map(property_code, vlist, canon_map, filename_root + '.txt')
36        self.enum_value_map[property_code] = value_map
37
38    def load_ScriptExtensions_data(self):
39        filename_root = 'ScriptExtensions'
40        property_code = 'scx'
41        vlist = self.property_value_list['sc']
42        (prop_values, value_map) = parse_ScriptExtensions_txt(vlist, self.property_value_lookup_map['sc'])
43        self.enum_value_map['scx'] = value_map
44       
45    def load_binary_properties_data(self, filename_root):
46        (props, prop_map) = parse_UCD_codepoint_name_map(filename_root + '.txt', self.property_lookup_map)
47        for p in props:
48            self.binary_value_map[p] = prop_map[p]
49
50    def load_others(self):
51        self.others = ['Alphabetic', 'Uppercase', 'Lowercase', 'White_Space', 'Noncharacter_Code_Point', 'Default_Ignorable_Code_Point', 'ANY', 'ASCII', 'ASSIGNED']
52        self.binary_value_map['ANY'] = range_uset(0, 0x10FFFF)
53        self.binary_value_map['ASCII'] = range_uset(0, 0x7F)
54        self.binary_value_map['ASSIGNED'] = uset_complement(self.enum_value_map['gc']['Cn'])     
55        self.binary_value_map['White_Space'] = self.binary_value_map['WSpace']
56        self.binary_value_map['Uppercase'] = self.binary_value_map['Upper']
57        self.binary_value_map['Lowercase'] = self.binary_value_map['Lower']
58        self.binary_value_map['Alphabetic'] = self.binary_value_map['Alpha']
59        self.binary_value_map['Noncharacter_Code_Point'] = self.binary_value_map['NChar']
60        self.binary_value_map['Default_Ignorable_Code_Point'] = self.binary_value_map['DI']
61
62    def load_all(self):
63        # First parse all property names and their aliases
64        self.load_property_name_info()
65        #
66        # Next parse all property value names and their aliases.  Generate the data.
67        self.load_property_value_info()
68        #
69        # The Block property
70        self.load_enumerated_property_data('Blocks', 'blk')
71        #
72        # Scripts
73        self.load_enumerated_property_data('Scripts', 'sc')
74        #
75        # Script Extensions
76        self.load_ScriptExtensions_data()
77        #
78        # General Category
79        self.load_enumerated_property_data('extracted/DerivedGeneralCategory', 'gc')
80        #
81        # Core Properties
82        self.load_binary_properties_data('DerivedCoreProperties')
83        #
84        self.load_binary_properties_data('PropList')
85
86        self.load_others()
87
88    def generate_level_1_property_terms(self):
89        template = r"""<grepcase regexp="^\%s{%s}$" datafile="All_good" grepcount="%i"/>"""
90        terms = []
91        for p in self.others:
92            s = self.binary_value_map[p]
93            lbl = 'p'
94            neg = randint(0,1)
95            if neg == 1:
96                s = uset_complement(s)
97                lbl = 'P'
98            terms.append(template % (lbl, p, uset_popcount(uset_intersection(self.all_good_set, s))))
99        for v in self.property_value_list['gc']:
100            s = self.enum_value_map['gc'][v]
101            lbl = 'p'
102            neg = randint(0,1)
103            if neg == 1:
104                s = uset_complement(s)
105                lbl = 'P'
106            terms.append(template % (lbl, v, uset_popcount(uset_intersection(self.all_good_set, s))))
107        for v in self.property_value_list['sc']:
108            s = self.enum_value_map['sc'][v]
109            lbl = 'p'
110            neg = randint(0,1)
111            if neg == 1:
112                s = uset_complement(s)
113                lbl = 'P'
114            terms.append(template % (lbl, v, uset_popcount(uset_intersection(self.all_good_set, s))))
115        for v in self.property_value_list['sc']:
116            s = self.enum_value_map['scx'][v]
117            lbl = 'p'
118            neg = randint(0,1)
119            if neg == 1:
120                s = uset_complement(s)
121                lbl = 'P'
122            terms.append(template % (lbl, "scx=" + v, uset_popcount(uset_intersection(self.all_good_set, s))))
123        return terms
124
125    def random_binary(self, a1, a2):
126        (p1, t1) = a1
127        (p2, t2) = a2
128        neg1 = randint(0,1)
129        neg2 = randint(0,1)
130        op = randint(0,2)
131        s1 = self.enum_value_map[p1][t1]
132        if p2 == 'others': 
133            s2 = self.binary_value_map[t2]
134        else: s2 = self.enum_value_map[p2][t2]
135        if neg1 == 1: s1 = uset_complement(s1)
136        if neg2 == 1: s2 = uset_complement(s2)
137        if op == 0: s3 = uset_intersection(s1, s2)
138        elif op == 1: s3 = uset_difference(s1, s2)
139        elif op == 2: s3 = uset_union(s1, s2)
140        s3 = uset_intersection(s3, self.all_good_set)
141        if p1 == 'scx': t1 = 'scx=' + t1
142        if p2 == 'scx': t2 = 'scx=' + t2
143        v1 = "\\%s{%s}" % (['p', 'P'][neg1], t1)
144        v2 = "\\%s{%s}" % (['p', 'P'][neg2], t2)
145        opr = ["&amp;&amp;", "--", ""][op]
146        return r"""<grepcase regexp="^[%s%s%s]$" datafile="All_good" grepcount="%i"/>""" % (v1, opr, v2, uset_popcount(s3))
147
148    def generate_random_property_expressions(self):
149        gc = self.property_value_list['gc']
150        sc = self.property_value_list['sc']
151        others = ['Alphabetic', 'Uppercase', 'Lowercase', 'White_Space', 'Noncharacter_Code_Point', 'Default_Ignorable_Code_Point', 'ANY', 'ASCII', 'ASSIGNED']
152        exprs = []
153        for p in gc:
154           s = sc[randint(0, len(sc)-1)]
155           exprs.append(self.random_binary(('gc', p), ('sc', s)))           
156           sx = sc[randint(0, len(sc)-1)]
157           exprs.append(self.random_binary(('gc', p), ('scx', sx)))
158           othr = others[randint(0, len(others)-1)]
159           exprs.append(self.random_binary(('gc', p), ('others', othr)))
160        for p in sc:
161           g = gc[randint(0, len(gc)-1)]
162           exprs.append(self.random_binary(('sc', p), ('gc', g)))           
163           sx = sc[randint(0, len(sc)-1)]
164           exprs.append(self.random_binary(('sc', p), ('scx', sx)))
165           othr = others[randint(0, len(others)-1)]
166           exprs.append(self.random_binary(('sc', p), ('others', othr)))
167        for p in others:
168           s = sc[randint(0, len(sc)-1)]
169           exprs.append(self.random_binary(('sc', s), ('others', p)))
170           sx = sc[randint(0, len(sc)-1)]
171           exprs.append(self.random_binary(('scx', sx), ('others', p)))
172        return exprs
173
174def UCD_main():
175    ucd = UCD_test_generator()
176    ucd.load_all()
177    for t in ucd.generate_level_1_property_terms():
178        print t
179    for p in ucd.generate_random_property_expressions():
180        print p
181
182if __name__ == "__main__":
183    set_UCD_dir('UCD/7.0.0')
184    UCD_main()
Note: See TracBrowser for help on using the repository browser.