source: trunk/src/bitlex.c @ 54

Last change on this file since 54 was 54, checked in by cameron, 11 years ago
File size: 31.0 KB
Line 
1/*  bitlex - Parabix lexical analysis common routines.
2    Copyright (c) 2007, 2008, Robert D. Cameron.
3    Licensed to the public under the Open Software License 3.0.
4    Licensed to International Characters, Inc., under the Academic
5    Free License 3.0.
6
7*/
8
9#include "bitlex.h"
10#include "../lib/lib_simd.h"
11
12
13Lexer_Interface::Lexer_Interface(XML_Buffer_Interface *b, LexicalStreamSet *l) {
14        xml_buf = b;
15        parsing_engine_data = l;
16        x8basis = (BitBlockBasis *) simd_new(BUFFER_SIZE/PACKSIZE);
17};
18
19
20Lexer_Interface::~Lexer_Interface() {
21        simd_delete((SIMD_type *) x8basis);
22};
23
24
25
26void NoEncodingError(char * msg) {
27        printf("Error : %s\n", msg);
28        exit(-1);
29}
30
31void EncodingError(char * msg, unsigned char * enc_ptr, int lgth) {
32        printf("Error : Illegal/unsupported %s encoding of length %i: \"", msg, lgth);
33        for (int i = 0; i < lgth; i++) printf("%c", enc_ptr[i]);
34        printf("\"\n"); 
35        exit(-1);
36}
37
38template <>
39Lexer_Interface * Lexer<ASCII>::LexerFactory(XML_Buffer_Interface *b, LexicalStreamSet *l) {
40        if (!(b->has_encoding_decl)) {
41                // Must be UTF-8 or UTF-16; UTF-16 requires a ByteOrderMark.
42                if (b->code_unit_size == SingleByte) return new UTF_8_Lexer(b, l);
43                else if ((b->code_unit_size == DoubleByte))
44                        if (b->BOM_units == 1) return new UTF_16_Lexer(b, l);
45                        else NoEncodingError("UTF-16 implied but no byte order found.");
46                else NoEncodingError("UTF-32 without an encoding declaration.\n");
47        }
48        else {
49                unsigned char * enc_ptr = 
50                        &(((unsigned char *)(b->x8data))[b->encoding_start_pos]);
51                int lgth = b->encoding_lgth;
52                CodeUnit_ByteOrder order = b->byte_order;
53                switch (b->code_unit_size) {
54                case SingleByte:
55                        if ((lgth == 5) && at_UTF_8(enc_ptr))
56                                return new UTF_8_Lexer(b, l);
57                        else if ((lgth == 5) && at_ASCII(enc_ptr))
58                                return new ASCII_7_Lexer(b, l);
59                        else if ((lgth == 6)  && at_Latin1(enc_ptr))
60                                return new EASCII_8_Lexer(b, l);
61                        /* Really need a table-based lookup here */
62                        else EncodingError("8-bit", enc_ptr, lgth);
63                case DoubleByte:
64                        if (b->BOM_units == 1) 
65                                if ((lgth == 6) && at_UTF_16(enc_ptr))
66                                        return new UTF_16_Lexer(b, l);
67                                else if ((lgth == 5) && at_UCS_2(enc_ptr))
68                                        return new UCS_2_Lexer(b, l);
69                                else EncodingError("16-bit", enc_ptr, lgth);
70                        else if (order == BigEndian)
71                                if ((lgth == 8) && at_UTF_16BE(enc_ptr))
72                                        return new UTF_16_Lexer(b, l);
73                                else if ((lgth == 7) && at_UCS_2BE(enc_ptr))
74                                        return new UCS_2_Lexer(b, l);
75                                else EncodingError("16BE", enc_ptr, lgth);
76                        else /*if (order == LittleEndian)*/
77                                if ((lgth == 8) && at_UTF_16LE(enc_ptr))
78                                        return new UTF_16_Lexer(b, l);
79                                else if ((lgth == 7) && at_UCS_2LE(enc_ptr))
80                                        return new UCS_2_Lexer(b, l);
81                                else EncodingError("16LE", enc_ptr, lgth);
82                case QuadByte:
83                        if (b->BOM_units == 1) 
84                                if ((lgth == 6) && at_UTF_32(enc_ptr))
85                                        return new UTF_32_Lexer(b, l);
86                                else if ((lgth == 5) && at_UCS_4(enc_ptr))
87                                        return new UTF_32_Lexer(b, l);
88                                else EncodingError("32-bit", enc_ptr, lgth);
89                        else if (order == BigEndian)
90                                if ((lgth == 8) && at_UTF_32BE(enc_ptr))
91                                        return new UTF_32_Lexer(b, l);
92                                else if ((lgth == 7) && at_UCS_4BE(enc_ptr))
93                                        return new UTF_32_Lexer(b, l);
94                                else EncodingError("32BE", enc_ptr, lgth);
95                        else if (order == LittleEndian)
96                                if ((lgth == 8) && at_UTF_32LE(enc_ptr))
97                                        return new UTF_32_Lexer(b, l);
98                                else if ((lgth == 7) && at_UCS_4LE(enc_ptr))
99                                        return new UTF_32_Lexer(b, l);
100                                else EncodingError("32LE", enc_ptr, lgth);
101                        else EncodingError("32-bit", enc_ptr, lgth);
102                }
103        }
104}
105
106template <>
107Lexer_Interface * Lexer<EBCDIC>::LexerFactory(XML_Buffer_Interface *b, LexicalStreamSet *l) {
108        if (!(b->has_encoding_decl)) {
109                // Must be UTF-8 or UTF-16; UTF-16 requires a ByteOrderMark.
110                NoEncodingError("EBCDIC-family inferred, but no encoding declaration present.\n");
111        }
112        else {
113                unsigned char * enc_ptr = 
114                        &(((unsigned char *)(b->x8data))[b->encoding_start_pos]);
115                int lgth = b->encoding_lgth;
116
117                /* Really need a table-based lookup here */
118                if ((lgth == 6) && at_EBCDIC(enc_ptr))
119                        return new EBCDIC_Lexer(b, l);
120                else EncodingError("EBCDIC family", enc_ptr, lgth);
121        }
122}
123
124template <CodeUnit_Base C>
125Lexer<C>::Lexer(XML_Buffer_Interface *b, LexicalStreamSet *l) : Lexer_Interface::Lexer_Interface(b, l) {
126}
127
128UTF_8_Lexer::UTF_8_Lexer(XML_Buffer_Interface *b, LexicalStreamSet *l) : Lexer<ASCII>::Lexer(b, l) {
129}
130
131ASCII_7_Lexer::ASCII_7_Lexer(XML_Buffer_Interface *b, LexicalStreamSet *l) : Lexer<ASCII>::Lexer(b, l) {
132}
133
134EASCII_8_Lexer::EASCII_8_Lexer(XML_Buffer_Interface *b, LexicalStreamSet *l) : Lexer<ASCII>::Lexer(b, l) {
135}
136
137U16_Lexer::U16_Lexer(XML_Buffer_Interface *b, LexicalStreamSet *l) : Lexer<ASCII>::Lexer(b, l) {
138}
139
140UTF_16_Lexer::UTF_16_Lexer(XML_Buffer_Interface *b, LexicalStreamSet *l) : U16_Lexer::U16_Lexer(b, l) {
141}
142
143UCS_2_Lexer::UCS_2_Lexer(XML_Buffer_Interface *b, LexicalStreamSet *l) : U16_Lexer::U16_Lexer(b, l) {
144}
145
146UTF_32_Lexer::UTF_32_Lexer(XML_Buffer_Interface *b, LexicalStreamSet *l) : Lexer<ASCII>::Lexer(b, l) {
147}
148
149EBCDIC_Lexer::EBCDIC_Lexer(XML_Buffer_Interface *b, LexicalStreamSet *l) : Lexer<EBCDIC>::Lexer(b, l) {
150}
151
152template <CodeUnit_Base C>
153static inline void WS_Control_Blocks(BitBlock bit[], BitBlock& WS, BitBlock& Control);
154
155template <>
156static inline void WS_Control_Blocks<ASCII>(BitBlock bit[], BitBlock& WS, BitBlock& Control) {
157        BitBlock temp1 = simd_or(bit[0], bit[1]);
158        BitBlock temp2 = simd_or(temp1, bit[2]);
159        Control = simd_andc(simd_const_1(1), temp2);
160        BitBlock temp3 = simd_or(bit[2], bit[3]);
161        BitBlock temp4 = simd_or(temp1, temp3);
162        BitBlock temp5 = simd_and(bit[4], bit[5]);
163        BitBlock temp6 = simd_andc(bit[7], bit[6]);
164        BitBlock temp7 = simd_and(temp5, temp6);
165        BitBlock CR = simd_andc(temp7, temp4);
166        BitBlock temp8 = simd_andc(bit[4], bit[5]);
167        BitBlock temp9 = simd_andc(bit[6], bit[7]);
168        BitBlock temp10 = simd_and(temp8, temp9);
169        BitBlock LF = simd_andc(temp10, temp4);
170        BitBlock temp11 = simd_and(temp8, temp6);
171        BitBlock HT = simd_andc(temp11, temp4);
172        BitBlock temp12 = simd_andc(bit[2], bit[3]);
173        BitBlock temp13 = simd_andc(temp12, temp1);
174        BitBlock temp14 = simd_or(bit[4], bit[5]);
175        BitBlock temp15 = simd_or(bit[6], bit[7]);
176        BitBlock temp16 = simd_or(temp14, temp15);
177        BitBlock SP = simd_andc(temp13, temp16);
178        WS = simd_or(simd_or(CR, LF), simd_or(HT, SP));
179}
180
181template <>
182static inline void WS_Control_Blocks<EBCDIC>(BitBlock bit[], BitBlock& WS, BitBlock& Control) {
183        BitBlock temp1 = simd_or(bit[0], bit[1]);
184        BitBlock temp2 = simd_or(bit[2], bit[3]);
185        BitBlock temp3 = simd_or(temp1, temp2);
186        BitBlock temp4 = simd_or(bit[4], bit[5]);
187        BitBlock temp5 = simd_or(temp3, temp4);
188        BitBlock temp6 = simd_and(bit[2], bit[3]);
189        BitBlock temp7 = simd_andc(temp6, temp1);
190        BitBlock temp8 = simd_andc(bit[5], bit[4]);
191        BitBlock temp9 = simd_and(bit[6], bit[7]);
192        BitBlock temp10 = simd_and(temp8, temp9);
193        BitBlock temp11 = simd_and(temp7, temp10);
194        BitBlock temp12 = simd_andc(temp5, temp11);
195        BitBlock temp13 = simd_andc(bit[2], bit[3]);
196        BitBlock temp14 = simd_andc(temp13, temp1);
197        BitBlock temp15 = simd_and(bit[4], bit[5]);
198        BitBlock temp16 = simd_and(temp14, temp15);
199        BitBlock temp17 = simd_andc(bit[6], bit[7]);
200        BitBlock temp18 = simd_andc(temp16, temp17);
201        BitBlock temp19 = simd_andc(temp12, temp18);
202        BitBlock temp20 = simd_andc(bit[3], bit[2]);
203        BitBlock temp21 = simd_andc(temp20, temp1);
204        BitBlock temp22 = simd_and(temp8, temp17);
205        BitBlock temp23 = simd_and(temp21, temp22);
206        BitBlock temp24 = simd_andc(temp19, temp23);
207        BitBlock temp25 = simd_or(temp1, bit[2]);
208        BitBlock temp26 = simd_or(bit[5], temp9);
209        BitBlock temp27 = simd_and(bit[4], temp26);
210        BitBlock temp28 = simd_andc(simd_const_1(1), temp4);
211        BitBlock temp29 = simd_if(bit[3], temp27, temp28);
212        BitBlock temp30 = simd_andc(temp29, temp25);
213        BitBlock temp31 = simd_andc(temp24, temp30);
214        BitBlock temp32 = simd_andc(temp15, bit[6]);
215        BitBlock temp33 = simd_and(temp7, temp32);
216        BitBlock temp34 = simd_andc(temp31, temp33);
217        BitBlock temp35 = simd_andc(temp17, temp4);
218        BitBlock temp36 = simd_and(temp7, temp35);
219        BitBlock temp37 = simd_andc(temp34, temp36);
220        BitBlock temp38 = simd_and(temp8, bit[6]);
221        BitBlock temp39 = simd_and(temp14, temp38);
222        BitBlock temp40 = simd_andc(temp37, temp39);
223        BitBlock temp41 = simd_andc(bit[4], bit[5]);
224        BitBlock temp42 = simd_andc(temp41, bit[6]);
225        BitBlock temp43 = simd_and(temp21, temp42);
226        BitBlock temp44 = simd_andc(temp40, temp43);
227        BitBlock temp45 = simd_and(temp15, temp9);
228        BitBlock temp46 = simd_and(temp7, temp45);
229        BitBlock temp47 = simd_andc(temp44, temp46);
230        BitBlock temp48 = simd_and(temp21, temp15);
231        BitBlock temp49 = simd_andc(temp47, temp48);
232        Control = simd_andc(simd_const_1(1), temp49);
233        BitBlock temp50 = simd_andc(bit[7], bit[6]);
234        BitBlock temp51 = simd_and(temp15, temp50);
235        BitBlock CR = simd_andc(temp51, temp3);
236        BitBlock temp52 = simd_and(temp8, temp50);
237        BitBlock LF = simd_and(temp14, temp52);
238        BitBlock HT = simd_andc(temp52, temp3);
239        BitBlock temp53 = simd_andc(bit[1], bit[0]);
240        BitBlock temp54 = simd_andc(temp53, temp2);
241        BitBlock temp55 = simd_or(bit[6], bit[7]);
242        BitBlock temp56 = simd_or(temp4, temp55);
243        BitBlock SP = simd_andc(temp54, temp56);
244        WS = simd_or(simd_or(CR, LF), simd_or(HT, SP));
245}
246
247
248
249template <CodeUnit_Base C>
250void Lexer<C>::Do_XML_10_WS_Control() {
251        BitBlock Restricted = simd_const_1(0);
252        BitBlock Control = simd_const_1(0);
253        BitBlock WS = simd_const_1(0);
254        BitBlock final_block_mask;
255        for (int i = 0; i < buffer_blocks; i++) {
256                Restricted = simd_or(Restricted, simd_andc(Control, WS));
257                WS_Control_Blocks<C>(x8basis[i].bit, 
258                                     WS,
259                                     Control);
260                parsing_engine_data->item_stream[NonWS][i] = simd_not(WS);
261        }
262        if ((buffer_units % BLOCKSIZE) != 0) {
263                final_block_mask = sisd_sfl(simd_const_1(1),
264                                            sisd_from_int(buffer_units % BLOCKSIZE));
265                Control = simd_andc(Control, final_block_mask);
266        }
267        Restricted = simd_or(Restricted, simd_andc(Control, WS));
268        if (bitblock_has_bit(Restricted)) {
269                printf("Restricted control character in input.\n");
270                exit(-1);
271        }
272};
273
274
275template <CodeUnit_Base C>
276static inline void ComputeLexicalItemBlocks(BitBlock bit[], BitBlock LexItem[]);
277
278/* Given the bit[] array of one BitBlock each for the 8 bits of
279   an ASCII-family character representation, compute the parallel
280   lexical item streams needed for XML parsing.
281
282   WARNING: the following is generated code by charset_compiler.py.
283   Do not edit.
284
285*/
286
287template <>
288static inline void ComputeLexicalItemBlocks<ASCII>(BitBlock bit[], BitBlock LexItem[]) {
289        BitBlock temp1 = simd_or(bit[0], bit[1]);
290        BitBlock temp2 = simd_and(bit[2], bit[3]);
291        BitBlock temp3 = simd_andc(temp2, temp1);
292        BitBlock temp4 = simd_and(bit[4], bit[5]);
293        BitBlock temp5 = simd_or(bit[6], bit[7]);
294        BitBlock temp6 = simd_andc(temp4, temp5);
295        BitBlock temp7 = simd_and(temp3, temp6);
296        BitBlock temp8 = simd_andc(bit[2], bit[3]);
297        BitBlock temp9 = simd_andc(temp8, temp1);
298        BitBlock temp10 = simd_andc(bit[5], bit[4]);
299        BitBlock temp11 = simd_andc(bit[6], bit[7]);
300        BitBlock temp12 = simd_and(temp10, temp11);
301        BitBlock temp13 = simd_and(temp9, temp12);
302        LexItem[MarkupStart] = simd_or(temp7, temp13);
303        BitBlock temp14 = simd_and(temp4, temp11);
304        BitBlock RAngle = simd_and(temp3, temp14);
305        BitBlock temp15 = simd_andc(bit[1], bit[0]);
306        BitBlock temp16 = simd_andc(bit[3], bit[2]);
307        BitBlock temp17 = simd_and(temp15, temp16);
308        BitBlock temp18 = simd_andc(bit[7], bit[6]);
309        BitBlock temp19 = simd_and(temp4, temp18);
310        BitBlock RBracket = simd_and(temp17, temp19);
311        LexItem[Hyphen] = simd_and(temp9, temp19);
312        BitBlock temp20 = simd_and(bit[6], bit[7]);
313        BitBlock temp21 = simd_and(temp4, temp20);
314        LexItem[QMark] = simd_and(temp3, temp21);
315        BitBlock temp22 = simd_or(bit[4], bit[5]);
316        BitBlock temp23 = simd_andc(temp11, temp22);
317        BitBlock temp24 = simd_and(temp10, temp20);
318        BitBlock temp25 = simd_or(temp23, temp24);
319        BitBlock temp26 = simd_and(temp9, temp25);
320        BitBlock temp27 = simd_or(temp26, temp7);
321        LexItem[Quote] = simd_or(temp27, temp13);
322        BitBlock temp28 = simd_andc(bit[4], bit[5]);
323        BitBlock temp29 = simd_and(temp28, temp20);
324        BitBlock temp30 = simd_or(temp29, temp19);
325        BitBlock temp31 = simd_and(temp3, temp30);
326        BitBlock temp32 = simd_and(temp9, temp21);
327        BitBlock temp33 = simd_or(temp31, temp32);
328        BitBlock temp34 = simd_or(temp33, RAngle);
329        LexItem[NameFollow] = simd_or(temp34, LexItem[QMark]);
330       
331        /* Mark potential occurrences of ']]>'  These are all actual
332        occurrences of ]]> as well as occurrences of ]] or ] at
333        the block end. Shifting the RBracket and RAngle streams in
334        negated forms ensures that a potential CD_End is not ruled
335        out at the block boundary. */
336        LexItem[CD_End_check] = simd_andc(RBracket, 
337                                          simd_or(sisd_sbli(simd_not(RBracket), 1),
338                                                  sisd_sbli(simd_not(RAngle), 2)));
339#ifndef OMIT_CD_End_check_In_Markup_Scan
340        LexItem[MarkupStart] = simd_or(LexItem[MarkupStart], LexItem[CD_End_check]);
341#endif
342}
343
344template <>
345static inline void ComputeLexicalItemBlocks<EBCDIC>(BitBlock bit[], BitBlock LexItem[]) {
346        BitBlock temp1 = simd_andc(bit[1], bit[0]);
347        BitBlock temp2 = simd_or(bit[2], bit[3]);
348        BitBlock temp3 = simd_andc(temp1, temp2);
349        BitBlock temp4 = simd_and(bit[4], bit[5]);
350        BitBlock temp5 = simd_or(bit[6], bit[7]);
351        BitBlock temp6 = simd_andc(temp4, temp5);
352        BitBlock temp7 = simd_and(temp3, temp6);
353        BitBlock temp8 = simd_andc(bit[3], bit[2]);
354        BitBlock temp9 = simd_and(temp1, temp8);
355        BitBlock temp10 = simd_or(bit[4], bit[5]);
356        BitBlock temp11 = simd_or(temp10, temp5);
357        BitBlock temp12 = simd_andc(temp9, temp11);
358        LexItem[MarkupStart] = simd_or(temp7, temp12);
359        BitBlock temp13 = simd_andc(bit[2], bit[3]);
360        BitBlock temp14 = simd_and(temp1, temp13);
361        BitBlock temp15 = simd_andc(bit[6], bit[7]);
362        BitBlock temp16 = simd_and(temp4, temp15);
363        BitBlock RAngle = simd_and(temp14, temp16);
364        BitBlock temp17 = simd_andc(bit[0], bit[1]);
365        BitBlock temp18 = simd_and(bit[2], bit[3]);
366        BitBlock temp19 = simd_and(temp17, temp18);
367        BitBlock temp20 = simd_andc(bit[4], bit[5]);
368        BitBlock temp21 = simd_and(bit[6], bit[7]);
369        BitBlock temp22 = simd_and(temp20, temp21);
370        BitBlock RBracket = simd_and(temp19, temp22);
371        LexItem[Hyphen] = simd_andc(temp14, temp11);
372        BitBlock temp23 = simd_and(temp4, temp21);
373        LexItem[QMark] = simd_and(temp14, temp23);
374        BitBlock temp24 = simd_and(temp1, temp18);
375        BitBlock temp25 = simd_and(temp4, bit[7]);
376        BitBlock temp26 = simd_and(temp24, temp25);
377        BitBlock temp27 = simd_or(temp26, temp7);
378        LexItem[Quote] = simd_or(temp27, temp12);
379        BitBlock temp28 = simd_and(temp1, bit[3]);
380        BitBlock temp29 = simd_and(temp16, temp28);
381        BitBlock temp30 = simd_andc(bit[7], bit[6]);
382        BitBlock temp31 = simd_andc(temp30, temp10);
383        BitBlock temp32 = simd_and(temp14, temp31);
384        BitBlock temp33 = simd_or(temp29, temp32);
385        BitBlock temp34 = simd_or(temp33, RAngle);
386        LexItem[NameFollow] = simd_or(temp34, LexItem[QMark]);
387       
388        /* Mark potential occurrences of ']]>'  These are all actual
389        occurrences of ]]> as well as occurrences of ]] or ] at
390        the block end. Shifting the RBracket and RAngle streams in
391        negated forms ensures that a potential CD_End is not ruled
392        out at the block boundary. */
393        LexItem[CD_End_check] = simd_andc(RBracket, 
394                                          simd_or(sisd_sbli(simd_not(RBracket), 1),
395                                                  sisd_sbli(simd_not(RAngle), 2)));
396#ifndef OMIT_CD_End_check_In_Markup_Scan
397        LexItem[MarkupStart] = simd_or(LexItem[MarkupStart], LexItem[CD_End_check]);
398#endif
399}
400
401
402/* A temporary structure for internal use in ComputeLexicalItemStreams. */
403typedef struct {
404        BitBlock LexicalItems[LexicalItemCount];
405} LexicalItemBlock;
406
407
408
409
410template <CodeUnit_Base C>
411void Lexer<C>::Do_MarkupStreams() {
412        LexicalItemBlock lx_blk[BUFFER_BLOCKS];
413        for (int i = 0; i < buffer_blocks; i++) {
414                ComputeLexicalItemBlocks<C>(x8basis[i].bit, lx_blk[i].LexicalItems);
415        }
416#ifdef BUFFER_PROFILING
417        end_BOM_interval(bitstream_timer);
418        start_BOM_interval(lextranspose_timer);
419#endif
420        for (int j = MarkupStart; j < LexicalItemCount; j++) {
421                for (int i = 0; i < buffer_blocks; i++) {
422                        parsing_engine_data->item_stream[j][i] = lx_blk[i].LexicalItems[j];
423                }
424        }
425        for (int i = 0; i < buffer_blocks; i++) {
426                parsing_engine_data->item_stream[NameFollow][i] = 
427                        simd_or(parsing_engine_data->item_stream[NameFollow][i],
428                                simd_not(parsing_engine_data->item_stream[NonWS][i]));
429        }
430#ifdef BUFFER_PROFILING
431        end_BOM_interval(lextranspose_timer);
432        start_BOM_interval(scanner_timer);
433#endif
434};
435
436
437/* Stub out Charset Validation initially. */
438
439void UTF_8_Lexer::Do_CharsetValidation() {
440        //printf("UTF_8_Lexer::Do_CharsetValidation not yet implemented; assuming OK.\n");
441};
442
443
444void ASCII_7_Lexer::Do_CharsetValidation() {
445        BitBlock Restricted = simd_const_1(0);
446        for (int blk = 0; blk < buffer_blocks; blk++) {
447                Restricted = simd_or(Restricted, x8basis[blk].bit[0]);
448        }
449        if (bitblock_has_bit(Restricted)) {
450                printf("Illegal non-ASCII character in input for ASCII document.\n");
451                exit(-1);
452        }
453};
454
455
456void EASCII_8_Lexer::Do_CharsetValidation() {
457        /* Nothing required for most charsets - but perhaps should have tables. */
458};
459
460
461void UTF_16_Lexer::Do_CharsetValidation() {
462#ifdef X16HILO_ACCESS
463        int packs = (buffer_units - 1)/PACKSIZE + 1;
464        BytePack surrogate_select;
465        BytePack hi_surrogate;
466        BytePack lo_surrogate;
467        BytePack hi_surrogate_pending = simd_const_8(0);
468        BytePack surrogate_scope;
469        BytePack u16_surrogate_accum = simd_const_8(0);
470        BytePack u16_FFFE_FFFF_accum = simd_const_8(0);
471        BytePack u16_FFFE_FFFF;
472        for (int pk = 0; pk < packs; pk++) {
473                /* UTF-16 code units in the range D800-DBFF and DC00-DFFF are
474                   reserved for the first and second elements, respectively
475                   of surrogate pairs.  Validation requires that these values
476                   only occur in well-formed pairs. */
477                surrogate_select = simd_and(x16hi[pk], simd_const_8(0xDC));
478                hi_surrogate = simd_eq_8(surrogate_select, simd_const_8(0xD8));
479                lo_surrogate = simd_eq_8(surrogate_select, simd_const_8(0xDC));
480                surrogate_scope = simd_or(hi_surrogate_pending,
481                                          sisd_sfli(hi_surrogate, 8));
482                u16_surrogate_accum = simd_or(u16_surrogate_accum,
483                                              simd_xor(surrogate_scope, lo_surrogate));
484                hi_surrogate_pending = sisd_sbli(hi_surrogate, 8 * (PACKSIZE-1));
485                /* The values FFFE and FFFF are excluded. */
486                u16_FFFE_FFFF = simd_eq_8(simd_and(x16hi[pk],
487                                                   simd_or(x16lo[pk], simd_const_8(1))),
488                                          simd_const_8(0xFF));
489                u16_FFFE_FFFF_accum = simd_or(u16_FFFE_FFFF_accum, u16_FFFE_FFFF);
490        }
491        u16_surrogate_accum = simd_or(u16_surrogate_accum, hi_surrogate_pending);
492        if (bitblock_has_bit(simd_or(u16_surrogate_accum, u16_FFFE_FFFF_accum)))
493                printf("UTF-16 validation error.\n");
494                exit(-1);
495        }
496#endif
497#ifndef X16HILO_ACCESS
498        printf("UTF_16_Lexer::Do_CharsetValidation not yet complete; assuming OK.\n");
499#endif
500};
501
502
503void UCS_2_Lexer::Do_CharsetValidation() {
504#ifdef X16HILO_ACCESS
505        int packs = (buffer_units - 1)/PACKSIZE + 1;
506        BytePack u16_surrogate_accum = simd_const_8(0);
507        BytePack u16_FFFE_FFFF_accum = simd_const_8(0);
508        BytePack u16_FFFE_FFFF;
509        for (int pk = 0; pk < packs; pk++) {
510                /* The high byte of UCS-2 code units cannot be in the range D8-DF.
511                   This corresponds to the D800-DFFF range of illegal codepoints
512                   reserved for UTF-16 surrogate pairs. Accumulate the results.
513                   To check, 0x20 is added to each such octet, mapping the D8-DF
514                   range to F8-FF and wrapping E0-FF values around.  The max value
515                   is then accumulated.  */
516                u16_surrogate_accum =
517                        simd_max_8(u16_surrogate_accum, 
518                                   simd_add_8(x16hi[pk], simd_const_8(0x20)));
519                /* The values FFFE and FFFF are excluded. */
520                u16_FFFE_FFFF = simd_eq_8(simd_and(x16hi[pk],
521                                                   simd_or(x16lo[pk], simd_const_8(1))),
522                                          simd_const_8(0xFF));
523                u16_FFFE_FFFF_accum = simd_or(u16_FFFE_FFFF_accum, u16_FFFE_FFFF);
524        }
525        u16_surrogate_accum = simd_eq_8(simd_or(u16_surrogate_accum, simd_const_8(0x07)),
526                                        simd_const_8(0xFF));
527        if (bitblock_has_bit(simd_or(u16_surrogate_accum, u16_FFFE_FFFF_accum)))
528                printf("UCS-2 validation error.\n");
529                exit(-1);
530        }
531#endif
532#ifndef X16HILO_ACCESS
533        printf("UCS_2_Lexer::Do_CharsetValidation not yet complete; assuming OK.\n");
534#endif
535};
536
537
538void UTF_32_Lexer::Do_CharsetValidation() {
539#ifdef X32BYTEPLEX_ACCESS
540        int packs = (buffer_units - 1)/PACKSIZE + 1;
541        BytePack u32hh_accum = simd_const_8(0);
542        BytePack u32hl_accum = simd_const_8(0);
543        BytePack u32_surrogate_accum = simd_const_8(0);
544        BytePack u32_FFFE_FFFF_accum = simd_const_8(0);
545        BytePack u32_BMP_select;
546        BytePack u32l_FFFE_FFFF;
547        for (int pk = 0; pk < packs; pk++) {
548                /* There can be no bits set in the high octet; "or" together
549                   all octet values to check for any bit set. */
550                u32hh_accum = simd_or(u32hh_accum, x32hh[pk]);
551                /* The second octet has a max value of 0x10, corresponding to the
552                   maximum Unicode code point value of 0x10FFFF.  Accumulate the
553                   maximum of all u32hl values observed. */ 
554                u32hl_accum = simd_max_8(u32hl_accum, x32hl[pk]);
555                /* The third octet cannot be in the range D8-DF if the second octet
556                   is 0.  This corresponds to the D800-DFFF range of illegal codepoints
557                   reserved for UTF-16 surrogate pairs. Accumulate the results.
558                   To check, 0x20 is added to each such octet, mapping the D8-DF
559                   range to F8-FF and wrapping E0-FF values around.  The max value
560                   is then accumulated.  */
561                u32_BMP_select = simd_eq_8(x32hl[pk], simd_const_8(0));
562                u32_surrogate_accum = 
563                        simd_max_8(u32_surrogate_accum, 
564                                   simd_and(u32_BMP_select,
565                                            simd_add_8(x32lh[pk], simd_const_8(0x20))));
566                /* The low two octets cannot have the value FFFE or FFFF if
567                   we're in the BMP (second octet is 0). */
568                u32l_FFFE_FFFF = simd_eq_8(simd_and(x32lh[pk],
569                                                    simd_or(x32ll[pk], simd_const_8(1))),
570                                           simd_const_8(0xFF));
571                u32_FFFE_FFFF_accum = simd_or(u32_FFFE_FFFF_accum,
572                                              simd_and(u32_BMP_select, u32l_FFFE_FFFF));
573        }
574        u32hl_accum = simd_gt_8(u32hl_accum, simd_const_8(0x10));
575        u32_surrogate_accum = simd_eq_8(simd_or(u32_surrogate_accum, simd_const_8(0x07)),
576                                        simd_const_8(0xFF));
577        if (bitblock_has_bit(simd_or(simd_or(u32hh_accum, u32hl_accum),
578                                         simd_or(u32_surrogate_accum, u32_FFFE_FFFF_accum)))) {
579                printf("UTF-32 validation error.\n");
580                exit(-1);
581        }
582#endif
583#ifndef X32BYTEPLEX_ACCESS
584        printf("UTF_32_Lexer::Do_CharsetValidation not yet complete; assuming OK.\n");
585#endif
586};
587
588
589void EBCDIC_Lexer::Do_CharsetValidation() {
590        /* Nothing required for most cases - but perhaps should have tables. */
591};
592
593
594
595
596/* Stub out XML 1.1 routines initially. */
597
598void UTF_8_Lexer::Do_XML_11_WS_Control() {
599        printf("UTF_8_Lexer::Do_XML_11_WS_Control not yet implemented; using XML 1.0 rules.\n");
600        Do_XML_10_WS_Control();
601};
602
603
604static inline void ASCII_7_WS_Control_Blocks_11(BitBlock bit[], BitBlock& WS, BitBlock& Control) {
605        BitBlock temp1 = simd_or(bit[0], bit[1]);
606        BitBlock temp2 = simd_or(temp1, bit[2]);
607        BitBlock temp3 = simd_andc(bit[1], bit[0]);
608        BitBlock temp4 = simd_and(bit[2], bit[3]);
609        BitBlock temp5 = simd_and(temp3, temp4);
610        BitBlock temp6 = simd_and(bit[4], bit[5]);
611        BitBlock temp7 = simd_and(bit[6], bit[7]);
612        BitBlock temp8 = simd_and(temp6, temp7);
613        BitBlock temp9 = simd_and(temp5, temp8);
614        BitBlock temp10 = simd_andc(temp2, temp9);
615        BitBlock temp11 = simd_andc(temp10, bit[0]);
616        Control = simd_andc(simd_const_1(1), temp11);
617        BitBlock temp12 = simd_or(bit[2], bit[3]);
618        BitBlock temp13 = simd_or(temp1, temp12);
619        BitBlock temp14 = simd_andc(bit[7], bit[6]);
620        BitBlock temp15 = simd_and(temp6, temp14);
621        BitBlock CR = simd_andc(temp15, temp13);
622        BitBlock temp16 = simd_andc(bit[4], bit[5]);
623        BitBlock temp17 = simd_andc(bit[6], bit[7]);
624        BitBlock temp18 = simd_and(temp16, temp17);
625        BitBlock LF = simd_andc(temp18, temp13);
626        BitBlock temp19 = simd_and(temp16, temp14);
627        BitBlock HT = simd_andc(temp19, temp13);
628        BitBlock temp20 = simd_andc(bit[2], bit[3]);
629        BitBlock temp21 = simd_andc(temp20, temp1);
630        BitBlock temp22 = simd_or(bit[4], bit[5]);
631        BitBlock temp23 = simd_or(bit[6], bit[7]);
632        BitBlock temp24 = simd_or(temp22, temp23);
633        BitBlock SP = simd_andc(temp21, temp24);
634        WS = simd_or(simd_or(CR, LF), simd_or(HT, SP));
635}
636
637
638void ASCII_7_Lexer::Do_XML_11_WS_Control() {
639        BitBlock Restricted = simd_const_1(0);
640        BitBlock Control = simd_const_1(0);
641        BitBlock WS = simd_const_1(0);
642        for (int i = 0; i < buffer_blocks; i++) {
643                Restricted = simd_or(Restricted, simd_andc(Control, WS));
644                ASCII_7_WS_Control_Blocks_11(x8basis[i].bit, WS, Control);
645                parsing_engine_data->item_stream[NonWS][i] = simd_not(WS);
646        }
647        if ((buffer_units % BLOCKSIZE) != 0) 
648                Control = simd_andc(Control,
649                                    sisd_sfl(simd_const_1(1), 
650                                             sisd_from_int(buffer_units % BLOCKSIZE)));
651        Restricted = simd_or(Restricted, simd_andc(Control, WS));
652        if (bitblock_has_bit(Restricted)) {
653                printf("***Restricted control character in input.\n");
654                exit(-1);
655        }
656};
657
658static inline void EASCII_8_WS_Control_Blocks_11(BitBlock bit[], BitBlock& WS, BitBlock& Control) {
659        BitBlock temp1 = simd_or(bit[0], bit[1]);
660        BitBlock temp2 = simd_or(temp1, bit[2]);
661        BitBlock temp3 = simd_andc(bit[1], bit[0]);
662        BitBlock temp4 = simd_and(bit[2], bit[3]);
663        BitBlock temp5 = simd_and(temp3, temp4);
664        BitBlock temp6 = simd_and(bit[4], bit[5]);
665        BitBlock temp7 = simd_and(bit[6], bit[7]);
666        BitBlock temp8 = simd_and(temp6, temp7);
667        BitBlock temp9 = simd_and(temp5, temp8);
668        BitBlock temp10 = simd_andc(temp2, temp9);
669        BitBlock temp11 = simd_andc(bit[0], bit[1]);
670        BitBlock temp12 = simd_andc(temp11, bit[2]);
671        BitBlock temp13 = simd_andc(temp10, temp12);
672        Control = simd_andc(simd_const_1(1), temp13);
673        BitBlock temp14 = simd_or(bit[2], bit[3]);
674        BitBlock temp15 = simd_or(temp1, temp14);
675        BitBlock temp16 = simd_andc(bit[7], bit[6]);
676        BitBlock temp17 = simd_and(temp6, temp16);
677        BitBlock CR = simd_andc(temp17, temp15);
678        BitBlock temp18 = simd_andc(bit[4], bit[5]);
679        BitBlock temp19 = simd_andc(bit[6], bit[7]);
680        BitBlock temp20 = simd_and(temp18, temp19);
681        BitBlock LF = simd_andc(temp20, temp15);
682        BitBlock temp21 = simd_and(temp18, temp16);
683        BitBlock HT = simd_andc(temp21, temp15);
684        BitBlock temp22 = simd_andc(bit[2], bit[3]);
685        BitBlock temp23 = simd_andc(temp22, temp1);
686        BitBlock temp24 = simd_or(bit[4], bit[5]);
687        BitBlock temp25 = simd_or(bit[6], bit[7]);
688        BitBlock temp26 = simd_or(temp24, temp25);
689        BitBlock SP = simd_andc(temp23, temp26);
690        BitBlock temp27 = simd_andc(temp11, temp14);
691        BitBlock temp28 = simd_andc(bit[5], bit[4]);
692        BitBlock temp29 = simd_and(temp28, temp16);
693        BitBlock NEL = simd_and(temp27, temp29);
694        WS = simd_or(simd_or(simd_or(CR, LF), simd_or(HT, SP)), NEL);
695}
696
697void EASCII_8_Lexer::Do_XML_11_WS_Control() {
698        BitBlock Restricted = simd_const_1(0);
699        BitBlock Control = simd_const_1(0);
700        BitBlock WS = simd_const_1(0);
701        for (int i = 0; i < buffer_blocks; i++) {
702                Restricted = simd_or(Restricted, simd_andc(Control, WS));
703                EASCII_8_WS_Control_Blocks_11(x8basis[i].bit, WS, Control);
704                parsing_engine_data->item_stream[NonWS][i] = simd_not(WS);
705        }
706        if ((buffer_units % BLOCKSIZE) != 0) 
707                Control = simd_andc(Control,
708                                    sisd_sfl(simd_const_1(1), 
709                                             sisd_from_int(buffer_units % BLOCKSIZE)));
710        Restricted = simd_or(Restricted, simd_andc(Control, WS));
711        if (bitblock_has_bit(Restricted)) {
712                printf("***Restricted control character in input.\n");
713                exit(-1);
714        }
715};
716
717
718void U16_Lexer::Do_XML_11_WS_Control() {
719        printf("U16_Lexer::Do_XML_11_WS_Control not yet implemented; using XML 1.0 rules.\n");
720        Do_XML_10_WS_Control();
721};
722
723
724void UTF_32_Lexer::Do_XML_11_WS_Control() {
725        printf("UTF_32_Lexer::Do_XML_11_WS_Control not yet implemented; using XML 1.0 rules.\n");
726        Do_XML_10_WS_Control();
727};
728
729static inline void EBCDIC_WS_Control_Blocks_11(BitBlock bit[], BitBlock& WS, BitBlock& Control) {
730        BitBlock temp1 = simd_or(bit[0], bit[1]);
731        BitBlock temp2 = simd_and(bit[0], bit[1]);
732        BitBlock temp3 = simd_and(bit[2], bit[3]);
733        BitBlock temp4 = simd_and(temp2, temp3);
734        BitBlock temp5 = simd_and(bit[4], bit[5]);
735        BitBlock temp6 = simd_and(bit[6], bit[7]);
736        BitBlock temp7 = simd_and(temp5, temp6);
737        BitBlock temp8 = simd_and(temp4, temp7);
738        BitBlock temp9 = simd_andc(temp1, temp8);
739        Control = simd_andc(simd_const_1(1), temp9);
740        BitBlock temp10 = simd_or(bit[2], bit[3]);
741        BitBlock temp11 = simd_or(temp1, temp10);
742        BitBlock temp12 = simd_andc(bit[7], bit[6]);
743        BitBlock temp13 = simd_and(temp5, temp12);
744        BitBlock CR = simd_andc(temp13, temp11);
745        BitBlock temp14 = simd_andc(bit[2], bit[3]);
746        BitBlock temp15 = simd_andc(temp14, temp1);
747        BitBlock temp16 = simd_andc(bit[5], bit[4]);
748        BitBlock temp17 = simd_and(temp16, temp12);
749        BitBlock LF = simd_and(temp15, temp17);
750        BitBlock HT = simd_andc(temp17, temp11);
751        BitBlock temp18 = simd_andc(bit[1], bit[0]);
752        BitBlock temp19 = simd_andc(temp18, temp10);
753        BitBlock temp20 = simd_or(bit[4], bit[5]);
754        BitBlock temp21 = simd_or(bit[6], bit[7]);
755        BitBlock temp22 = simd_or(temp20, temp21);
756        BitBlock SP = simd_andc(temp19, temp22);
757        BitBlock temp23 = simd_andc(bit[3], bit[2]);
758        BitBlock temp24 = simd_andc(temp23, temp1);
759        BitBlock NEL = simd_and(temp24, temp17);
760        WS = simd_or(simd_or(simd_or(CR, LF), simd_or(HT, SP)), NEL);
761}
762
763void EBCDIC_Lexer::Do_XML_11_WS_Control() {
764        BitBlock Restricted = simd_const_1(0);
765        BitBlock Control = simd_const_1(0);
766        BitBlock WS = simd_const_1(0);
767        for (int i = 0; i < buffer_blocks; i++) {
768                Restricted = simd_or(Restricted, simd_andc(Control, WS));
769                EBCDIC_WS_Control_Blocks_11(x8basis[i].bit, WS, Control);
770                parsing_engine_data->item_stream[NonWS][i] = simd_not(WS);
771        }
772        if ((buffer_units % BLOCKSIZE) != 0) 
773                Control = simd_andc(Control,
774                                    sisd_sfl(simd_const_1(1), 
775                                             sisd_from_int(buffer_units % BLOCKSIZE)));
776        Restricted = simd_or(Restricted, simd_andc(Control, WS));
777        if (bitblock_has_bit(Restricted)) {
778                printf("***Restricted control character in input.\n");
779                exit(-1);
780        }
781};
782
783
784
785#include "transpose.h"
786
787void Lexer_Interface::TransposeToBitStreams() {
788        BytePack * pseudoASCII_src = &(xml_buf->x8data[lexer_base_pos/PACKSIZE]);
789        for (int blk = 0; blk < buffer_blocks; blk++) {
790                s2p_bytepack(&pseudoASCII_src[blk*8], x8basis[blk].bit);
791        }
792}
793
794void Lexer_Interface::AdvanceBuffer(int& base_pos, int& rel_pos, int& limit_pos) {
795        BitBlock final_block_mask;
796#ifdef BUFFER_PROFILING
797        start_BOM_interval(bitstream_timer);
798#endif
799#ifdef DEBUG
800        printf("AdvanceBuffer entry.\n");
801#endif
802        int abspos = base_pos + rel_pos;
803        lexer_base_pos = abspos & (-PACKSIZE); /* align the base_position for lexer*/
804        buffer_units = xml_buf->AvailableUnits(lexer_base_pos);
805#ifdef DEBUG
806        printf("buffer_units = %i.\n", buffer_units);
807#endif
808        if (buffer_units >= BUFFER_SIZE) {
809                buffer_units = BUFFER_SIZE;
810                final_block_mask = simd_const_1(0);
811        }
812        else {
813                final_block_mask = 
814                        sisd_sfl(simd_const_1(1), sisd_from_int(buffer_units % BLOCKSIZE));
815        }
816        buffer_blocks = (buffer_units -1)/BLOCKSIZE + 1;
817#ifdef DEBUG
818        printf("Transpose for abspos = %i, lexer_base_pos= %i, buffer_blocks = %i.\n", abspos, lexer_base_pos, buffer_blocks);
819#endif
820
821        TransposeToBitStreams();
822#ifdef DEBUG
823        printf("Transposition to bit streams complete.\n");
824#endif
825        if (xml_buf->version == XML_1_1) Do_XML_11_WS_Control();
826        else Do_XML_10_WS_Control();
827        Do_MarkupStreams();
828#ifdef DEBUG
829        printf("Markup streams complete.\n");
830#endif
831        Do_CharsetValidation();
832#ifdef DEBUG
833        printf("Validation complete.\n");
834#endif
835        if (buffer_units < BUFFER_SIZE) {
836#ifdef DEBUG
837                printf("SENTINELS at %i of length %i\n", lexer_base_pos + buffer_units,
838                                                buffer_units % BLOCKSIZE);
839#endif
840                int lastblk = buffer_units/BLOCKSIZE;
841                for (int j = minLexicalItem; j < LexicalItemCount; j++) {
842                        parsing_engine_data->item_stream[j][lastblk] =
843                                simd_or(parsing_engine_data->item_stream[j][lastblk],
844                                        final_block_mask);
845                }
846        }
847        /* Update parser control variables. */
848        base_pos = lexer_base_pos;
849        rel_pos = abspos - lexer_base_pos;
850        limit_pos = buffer_units;
851}
852
Note: See TracBrowser for help on using the repository browser.