source: icGREP/icgrep-devel/UCD-scripts/generate_UCD_tests.py @ 5671

Last change on this file since 5671 was 5653, checked in by cameron, 23 months ago

Updates for Python 3; some refactoring

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