Changeset 37 for trunk


Ignore:
Timestamp:
Feb 10, 2008, 6:19:06 AM (12 years ago)
Author:
cameron
Message:

Charset Architecture: Parser Factory

Location:
trunk/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/engine.c

    r27 r37  
    11/*  engine.c - Parabix XML parsing engine.
    2     Copyright (c) 2007, Robert D. Cameron.
     2    Copyright (c) 2007, 2008, Robert D. Cameron.
    33    Licensed to the public under the Open Software License 3.0.
    44    Licensed to International Characters, Inc., under the Academic
     
    1111#include "bytelex.h"
    1212#include "bitlex.h"
    13 #include "charsets/ext_ascii_8.h"
    14 #include "charsets/ext_ascii_16.h"
    1513
    1614#include <assert.h>
     
    1917#include <string.h>
    2018
    21 ParsingEngine::ParsingEngine (char * filename) {
     19
     20Parser_Interface * Parser_Interface::ParserFactory(char * filename) {
     21        XML_Buffer_Interface * b = XML_Buffer_Interface::BufferFactory(filename);
     22        b->DoByteplex();
     23        b->PreparePseudoASCII_Stream();
     24#ifdef DEBUG
     25        printf("PseudoASCII stream complete.\n");
     26#endif
     27        b->ReadXMLInfo();
     28#ifdef DEBUG
     29        printf("XML Info read; content start position = %i.\n", b->ContentStartUnit());
     30#endif
     31        if (b->code_unit_base == ASCII) {
     32                return new ParsingEngine<ASCII>(b);
     33        }
     34        else /* if (b->code_unit_base == EBCDIC) */ {
     35                return new ParsingEngine<EBCDIC>(b);
     36        }
     37}
     38
     39bool Parser_Interface::has_ByteOrderMark() {
     40        return xml_buf->BOM_units > 0;
     41}
     42
     43XML_version Parser_Interface::get_version() {
     44        return xml_buf->version;
     45}
     46
     47XML_standalone Parser_Interface::standalone_status() {
     48        return xml_buf->standalone;
     49}
     50
     51bool Parser_Interface::has_EncodingDecl() {
     52        return xml_buf->has_encoding_decl;
     53}
     54
     55int Parser_Interface::get_Encoding_pos() {
     56        return xml_buf->encoding_start_pos;
     57}
     58
     59int Parser_Interface::get_Encoding_lgth() {
     60        return xml_buf->encoding_lgth;
     61}
     62
     63
     64
     65
     66template <CodeUnit_Base C>
     67ParsingEngine<C>::ParsingEngine(XML_Buffer_Interface * b) : Parser_Interface () {
    2268#ifdef BUFFER_PROFILING
    2369        bitstream_timer = init_BOM_timer(BUFFER_BLOCKS * BLOCKSIZE);
     
    2571        scanner_timer = init_BOM_timer(BUFFER_BLOCKS * BLOCKSIZE);
    2672#endif
    27 
    28 #define OFFSET32_SENTINEL
     73/*      buf = new LexicalStreamSet;*/
     74        posix_memalign((void **) &buf, sizeof(BitBlock), sizeof(LexicalStreamSet));
     75#ifdef DEBUG
     76        printf("parser->buf addr = %x\n", (int) buf);
     77#endif
    2978
    3079  /* Install sentinels for every lexical item stream*/
    3180#ifndef OPTIMIZE_SHORT_SCAN
    32   BitBlock sentinel_value = simd_const_1(1);
     81        BitBlock sentinel_value = simd_const_1(1);
    3382#endif
    3483#ifdef OPTIMIZE_SHORT_SCAN
    35   BitBlock sentinel_value = sisd_sfli(simd_const_1(1), 8*sizeof(unsigned long));
    36 #endif
    37   for (int j = MarkupStart; j < LexicalItemCount; j++) {
    38     buf.item_stream[j][BUFFER_BLOCKS] = sentinel_value;
    39   }
    40   buffer_base_pos = 0;
    41   buffer_rel_pos = 0;
    42   xml_buf = new XML_Buffer::XML_Buffer(filename, BLOCKSIZE);
    43 }
    44 
    45 void ParsingEngine::InitLexer() {
    46   unsigned char * sentinel = (unsigned char *) "<![--?>]]>/'>\"><!";
    47   if (xml_buf->PrepareBytes(0, 4) < 4) {
    48     printf("No XML input document.\n");
    49     exit(-1);
    50   }
    51   unsigned char * XML_signature = xml_buf->BytePtr(0);
    52   xml_buf->InstallPadding(sentinel);
    53 
    54   Charset_Family family = Charset_Family_Detect(XML_signature);
    55   switch (family) {
    56     case Ext_ASCII_8:
    57       printf("Ext_ASCII_8 document detected.\n");
    58       lex = new Ext_ASCII_8_Lexer::Ext_ASCII_8_Lexer(xml_buf, &buf);
    59       //lex = new Lexer::Lexer(xml_buf, &buf);
    60       //xml_buf->InstallPadding(sentinel);
    61       break;
    62     case Ext_ASCII_16BE:
    63       printf("Ext_ASCII_16BE document detected.\n");
    64       lex = new Ext_ASCII_16BE_Lexer::Ext_ASCII_16BE_Lexer(xml_buf, &buf);
    65       break;
    66     case Ext_ASCII_16LE:
    67       printf("Ext_ASCII_16LE document detected.\n");
    68       lex = new Ext_ASCII_16LE_Lexer::Ext_ASCII_16LE_Lexer(xml_buf, &buf);
    69       break;
    70     default:
    71       printf("Error: Charset family %i detected, but not supported.\n", family);
    72       exit(-1);
    73   }
    74   avail_code_units = lex-> AdvanceBuffer(0);
    75 }
    76 
    77 
    78 inline void ParsingEngine::AdvanceToNewBasePosn(int advance_amt) {
    79   buffer_base_pos += advance_amt;
    80   buffer_rel_pos = 0;
    81 }
    82 
    83 inline unsigned char * ParsingEngine::cur() const {
    84   return &((unsigned char *) buf.x8data)[buffer_rel_pos];
    85 }
    86 
    87 
    88 inline int ParsingEngine::AbsPos() const {
     84        BitBlock sentinel_value = sisd_sfli(simd_const_1(1), 8*sizeof(unsigned long));
     85#endif
     86        for (int j = MarkupStart; j < LexicalItemCount; j++) {
     87                buf->item_stream[j][BUFFER_BLOCKS] = sentinel_value;
     88        }
     89#ifdef DEBUG
     90        printf("Bitspace sentinels established.\n");
     91#endif
     92        xml_buf = b;
     93        buffer_base_pos = 0;
     94        buffer_rel_pos = b->ContentStartUnit();
     95        lexer = Lexer<C>::LexerFactory(b, buf);
     96#ifdef DEBUG
     97        printf("Lexer created.\n");
     98#endif
     99        lexer->AdvanceBuffer(buffer_base_pos, buffer_rel_pos, buffer_limit_pos);
     100        x8data = &xml_buf->x8data[buffer_base_pos/PACKSIZE];
     101#ifdef DEBUG
     102        printf("Initial lexical buffer formed.\n");
     103#endif
     104}
     105
     106
     107
     108template <CodeUnit_Base C>
     109inline unsigned char * ParsingEngine<C>::cur() const {
     110  return &((unsigned char *) x8data)[buffer_rel_pos];
     111}
     112
     113template <CodeUnit_Base C>
     114inline int ParsingEngine<C>::AbsPos() const {
    89115  return buffer_base_pos + buffer_rel_pos;
    90116}
    91117
    92118
    93 inline int ParsingEngine::BufferRelPos() const {
     119template <CodeUnit_Base C>
     120inline int ParsingEngine<C>::BufferRelPos() const {
    94121  return buffer_rel_pos;
    95122}
    96123
    97124
    98 inline bool ParsingEngine::at_EOF () const {
    99   return (buffer_rel_pos >= avail_code_units) &&
    100          (avail_code_units < BUFFER_BLOCKS * BLOCKSIZE + LOOKAHEAD_POSITIONS);
    101 }
    102 
    103 inline void ParsingEngine::Advance(int n) {
     125template <CodeUnit_Base C>
     126inline bool ParsingEngine<C>::at_EOF() const {
     127  return (buffer_rel_pos >= buffer_limit_pos) &&
     128         (buffer_limit_pos < BUFFER_BLOCKS * BLOCKSIZE + LOOKAHEAD_POSITIONS);
     129}
     130
     131template <CodeUnit_Base C>
     132inline void ParsingEngine<C>::Advance(int n) {
    104133  buffer_rel_pos += n;
    105134#ifndef OMIT_BITBUFFER_LIMIT_TEST_IN_ADVANCE
    106   if (buffer_rel_pos >= BUFFER_BLOCKS * BLOCKSIZE) {
     135  if (buffer_rel_pos >= buffer_limit_pos) {
    107136    FinalizeBuffer_action();
    108137#ifdef BUFFER_PROFILING
    109138    end_BOM_interval(scanner_timer);
    110139#endif
    111     AdvanceToNewBasePosn(buffer_rel_pos);
    112     avail_code_units = lex->AdvanceBuffer(AbsPos());
     140    lexer->AdvanceBuffer(buffer_base_pos, buffer_rel_pos, buffer_limit_pos);
     141    x8data = &xml_buf->x8data[buffer_base_pos/PACKSIZE];
    113142  }
    114143#endif
    115144}
    116145
    117 inline void ParsingEngine::ASCII_ScanTo(int item) {
    118 #ifdef DEBUG_BYTESCAN
    119   int p1 = AbsPos();
    120 #endif
    121   switch (item) {
    122     case NonWS: while (at_WhiteSpace<XML_1_0, ASCII>(cur())) Advance(1); break;
    123     case MarkupStart: while(!AtChar<ASCII,'<'>(cur()) && !AtChar<ASCII,'&'>(cur()) && !at_CDATA_End<ASCII>(cur())) Advance(1); break;
    124     case CD_End_check: while(!at_CDATA_End<ASCII>(cur())) Advance(1); break;
    125     case Hyphen: while(!AtChar<ASCII,'-'>(cur())) Advance(1); break;
    126     case QMark: while(!AtChar<ASCII,'?'>(cur())) Advance(1); break;
    127     case DQuote: while(!AtChar<ASCII,'<'>(cur()) && !AtChar<ASCII,'&'>(cur()) && !AtChar<ASCII,'"'>(cur())) Advance(1); break;
    128     case SQuote: while(!AtChar<ASCII,'<'>(cur()) && !AtChar<ASCII,'&'>(cur()) && !AtChar<ASCII,'\''>(cur())) Advance(1); break;
    129     case NameFollow: while(!at_WhiteSpace<XML_1_0, ASCII>(cur()) && !AtChar<ASCII,';'>(cur()) && !AtChar<ASCII,'/'>(cur()) && !AtChar<ASCII,'>'>(cur())
    130                       && !AtChar<ASCII,'='>(cur()) && !AtChar<ASCII,'?'>(cur())) Advance(1); break;
    131   }
    132 #ifdef DEBUG_BYTESCAN
    133   printf("ASCII_ScanTo(%i) %i -> %i\n", item, p1, AbsPos());
    134 #endif
    135 }
    136146
    137147#ifndef OPTIMIZE_SHORT_SCAN
    138 #ifdef BYTESPACE_SCAN
    139 inline void ParsingEngine::ScanTo(int item) {
    140   ASCII_ScanTo(item);
    141 }
    142 #endif
    143 
    144 #ifndef BYTESPACE_SCAN
    145 inline void ParsingEngine::ScanTo(int item) {
    146   buffer_rel_pos = bitstream_scan(buf.item_stream[item],
     148template <CodeUnit_Base C>
     149inline void ParsingEngine<C>::ScanTo(int item) {
     150  buffer_rel_pos = bitstream_scan(buf->item_stream[item],
    147151                                      buffer_rel_pos);
    148   while (buffer_rel_pos >= BUFFER_BLOCKS * BLOCKSIZE) {
     152  while (buffer_rel_pos >= BUFFER_SIZE) {
    149153    FinalizeBuffer_action();
    150154#ifdef BUFFER_PROFILING
    151155    end_BOM_interval(scanner_timer);
    152156#endif
    153     AdvanceToNewBasePosn(buffer_rel_pos);
    154     avail_code_units = lex->AdvanceBuffer(AbsPos());
    155     buffer_rel_pos = bitstream_scan0(buf.item_stream[item]);
     157    lexer->AdvanceBuffer(buffer_base_pos, buffer_rel_pos, buffer_limit_pos);
     158#ifdef DEBUG
     159printf("lexer->AdvanceBuffer complete; base_pos = %i, rel_pos = %i, limit_pos = %i\n",
     160       buffer_base_pos, buffer_rel_pos, buffer_limit_pos);
     161#endif
     162    x8data = &xml_buf->x8data[buffer_base_pos/PACKSIZE];
     163    buffer_rel_pos = bitstream_scan(buf->item_stream[item], buffer_rel_pos);
    156164  }
    157165}
    158166#endif
    159 #endif
    160167
    161168#ifdef OPTIMIZE_SHORT_SCAN
    162 inline void ParsingEngine::ScanTo(int item) {
    163   SIMD_type * stream = buf.item_stream[item];
     169template <CodeUnit_Base C>
     170inline void ParsingEngine<C>::ScanTo(int item) {
     171  SIMD_type * stream = buf->item_stream[item];
    164172  unsigned long * bitstream_ptr = (unsigned long *) (((intptr_t) stream) + buffer_rel_pos/8);
    165173  unsigned long bitstream_slice = *bitstream_ptr >> buffer_rel_pos % 8;
     
    176184      end_BOM_interval(scanner_timer);
    177185#endif
    178       AdvanceToNewBasePosn(buffer_rel_pos);
    179       avail_code_units = lex->AdvanceBuffer(AbsPos());
    180       buffer_rel_pos = bitstream_scan0(buf.item_stream[item]);
     186      lexer->AdvanceBuffer(buffer_base_pos, buffer_rel_pos, buffer_limit_pos);
     187        x8data = &xml_buf->x8data[buffer_base_pos/PACKSIZE];
     188      buffer_rel_pos = bitstream_scan(buf->item_stream[item], buffer_rel_pos);
    181189    }
    182190  }
     
    186194
    187195/* Parse a markup item beginning '<' */
    188 inline void ParsingEngine::Parse_Markup () {
    189         int markup_start = AbsPos();
    190         if (at_ElementTag_Start<ASCII>(cur())) {
     196template <CodeUnit_Base C>
     197inline void ParsingEngine<C>::Parse_Markup() {
     198        int markup_start = AbsPos();
     199        if (at_ElementTag_Start<C>(cur())) {
    191200                Parse_StartTag();
    192201        }
    193         else if (at_EndTag_Start<ASCII>(cur())) {
     202        else if (at_EndTag_Start<C>(cur())) {
    194203                Parse_EndTag();
    195204        }
    196         else if (at_Comment_Start<ASCII>(cur())) {
     205        else if (at_Comment_Start<C>(cur())) {
    197206                Parse_Comment();
    198207        }
    199         else if (at_CDATA_Start<ASCII>(cur())) {
     208        else if (at_CDATA_Start<C>(cur())) {
    200209                Parse_CDATA();
    201210        }
    202         else if (at_PI_Start<ASCII>(cur())) {
     211        else if (at_PI_Start<C>(cur())) {
    203212                Parse_PI();
    204213        }
     
    210219
    211220/* Parse a comment beginning "<!--" */
    212 inline void ParsingEngine::Parse_Comment () {
     221template <CodeUnit_Base C>
     222inline void ParsingEngine<C>::Parse_Comment() {
    213223        int markup_start = AbsPos();
    214224        Advance(4); /* Skip "<!--". */
    215225        ScanTo(Hyphen);
    216         while (!at_DoubleHyphen<ASCII>(cur())) {
     226        while (!at_DoubleHyphen<C>(cur())) {
    217227                Advance(2); /* Skip hyphen-nonhyphen pair */
    218228                ScanTo(Hyphen);
    219229        }
    220         if (at_Comment_End<ASCII>(cur())) {
     230        if (at_Comment_End<C>(cur())) {
    221231                Advance(3); /* Skip "-->". */
    222232                Comment_action(markup_start, AbsPos());
     
    229239
    230240/* Parse an end tag beginning "</" */
    231 inline void ParsingEngine::Parse_EndTag () {
     241template <CodeUnit_Base C>
     242inline void ParsingEngine<C>::Parse_EndTag() {
    232243        int markup_start = AbsPos();
    233244#ifndef OMIT_ADVANCE_PRIOR_TO_EXCLUSIVE_SCAN
     
    235246#endif
    236247        ScanTo(NameFollow);
    237         if (AtChar<ASCII,'>'>(cur())) {
     248        if (AtChar<C,'>'>(cur())) {
    238249                Advance(1);
    239250                EndTag_action(markup_start, AbsPos());
     
    241252        else {
    242253                ScanTo(NonWS);
    243                 if (AtChar<ASCII,'>'>(cur())) {
     254                if (AtChar<C,'>'>(cur())) {
    244255                        Advance(1);
    245256                        EndTag_action(markup_start, AbsPos());
     
    250261
    251262/* Parse a CDATA section beginning "<![CDATA". */
    252 inline void ParsingEngine::Parse_CDATA () {
     263template <CodeUnit_Base C>
     264inline void ParsingEngine<C>::Parse_CDATA() {
    253265        int markup_start = AbsPos();
    254266        Advance(8); /* Skip "<![CDATA". */
    255         if (!AtChar<ASCII,'['>(cur())) {
     267        if (!AtChar<C,'['>(cur())) {
    256268                Error_action(markup_start, AbsPos());
    257269        }
    258270        else {
    259271                ScanTo(CD_End_check);
    260                 while (!at_CDATA_End<ASCII>(cur())) {
     272                while (!at_CDATA_End<C>(cur())) {
    261273                        Advance(1);
    262274                        ScanTo(CD_End_check);
     
    267279}
    268280
    269 inline void ParsingEngine::Parse_Reference () {
     281template <CodeUnit_Base C>
     282inline void ParsingEngine<C>::Parse_Reference() {
    270283        int markup_start = AbsPos();
    271284        /* Advance(1);  // skip "&" */
    272285        ScanTo(NameFollow);  /* Name delimiter */
    273         if (!AtChar<ASCII,';'>(cur())) {
     286        if (!AtChar<C,';'>(cur())) {
    274287                Error_action(markup_start, AbsPos());
    275288        }
     
    280293}
    281294
    282 inline void ParsingEngine::Parse_PI () {
     295template <CodeUnit_Base C>
     296inline void ParsingEngine<C>::Parse_PI (){
    283297        int markup_start = AbsPos();
    284298        Advance(2); /* Skip "<?". */
    285299        int target_start = AbsPos();
    286300        // Check for illegal [Xx][Mm][Ll] target.
    287         if (at_XxMmLll_WS<ASCII>(cur())) {
     301        if (at_XxMmLll_WS<C>(cur())) {
    288302                Advance(4);
    289303                Error_action(markup_start, AbsPos());
     
    293307        PI_Target_action(target_start, AbsPos());
    294308        ScanTo(QMark);
    295         while (!at_PI_End<ASCII>(cur())) {
     309        while (!at_PI_End<C>(cur())) {
    296310                Advance(1);
    297311                ScanTo(QMark);
     
    302316 
    303317/* Parse a start or empty element tag. */
    304 inline void ParsingEngine::Parse_StartTag () {
     318template <CodeUnit_Base C>
     319inline void ParsingEngine<C>::Parse_StartTag (){
    305320        int markup_start = AbsPos();
    306321        int att_name_start;
    307322        int att_val_start;
    308323        int att_name_end, att_val_end;
    309         lexical_item Quote_stream;
     324        unsigned char quoteCh;
    310325        ScanTo(NameFollow);  /* Name delimiter: WS, "/" or ">" */
    311326        ElementName_action(markup_start+1, AbsPos());
    312327        /* The following test optimizes the most common case of a
    313328        start tag with no attributes.  */
    314         if (AtChar<ASCII,'>'>(cur())) {
     329        if (AtChar<C,'>'>(cur())) {
    315330                Advance(1);
    316331                StartTag_action(markup_start, AbsPos());
     
    318333        else {
    319334                ScanTo(NonWS);
    320                 if (AtChar<ASCII,'>'>(cur())) {
     335                if (AtChar<C,'>'>(cur())) {
    321336                        Advance(1);
    322337                        StartTag_action(markup_start, AbsPos());
    323338                }
    324                 else if (at_EmptyElementDelim<ASCII>(cur())) {
     339                else if (at_EmptyElementDelim<C>(cur())) {
    325340                        Advance(2);
    326341                        EmptyElement_action(markup_start, AbsPos());
     
    335350                        In many cases, the very first test handles 100% of actual
    336351                        attribute-value pairs encountered. */
    337                         if (at_EqualsDQuote<ASCII>(cur())) {
     352                        if (at_EqualsQuote<C>(cur())) {
     353                                quoteCh = cur()[1];
    338354                                Advance(2);
    339                                 att_val_start = AbsPos();
    340                                 Quote_stream = DQuote;
    341                         }
    342                         else if (at_EqualsSQuote<ASCII>(cur())) {
    343                                 Advance(2);
    344                                 att_val_start = AbsPos();
    345                                 Quote_stream = SQuote;
    346355                        }
    347356                        else {
    348357                                ScanTo(NonWS);
    349                                 if (!AtChar<ASCII,'='>(cur())) {
     358                                if (!AtChar<C,'='>(cur())) {
    350359                                        Error_action(markup_start, AbsPos());
    351360                                        break;
    352361                                }
    353362                                ScanTo(NonWS);
    354                                 att_val_start = AbsPos()+1;
    355                                 if (AtChar<ASCII,'"'>(cur())) {
    356                                         Advance(1);
    357                                         Quote_stream = DQuote;
    358                                 }
    359                                 else if (AtChar<ASCII,'\''>(cur())) {
    360                                         Advance(1);
    361                                         Quote_stream = SQuote;
    362                                 }
    363                                 else {
     363                                quoteCh = cur()[0];
     364                                if (!AtQuote<C>(cur())) {
    364365                                        Error_action(markup_start, AbsPos());
    365366                                        break;
    366367                                }
    367                         }
    368                         ScanTo(Quote_stream);
    369                         while (AtChar<ASCII,'&'>(cur())) {
    370                                 Parse_Reference();
    371                                 ScanTo(Quote_stream);
    372                         }
    373                         if (AtChar<ASCII,'<'>(cur())) {
    374                                 Error_action(markup_start, AbsPos());
    375                                 break;
     368                                Advance(1);
     369                        }
     370                        att_val_start = AbsPos();
     371                        ScanTo(Quote);
     372                        while (cur()[0] != quoteCh) {
     373                                if (AtChar<C,'&'>(cur())) {
     374                                        Parse_Reference();
     375                                        ScanTo(Quote);
     376                                }
     377                                else if (AtQuote<C>(cur())) {
     378                                        Advance(1);
     379                                }
     380                                else /* if (AtChar<C,'<'>(cur())) */{
     381                                        Error_action(markup_start, AbsPos());
     382                                        break;
     383                                }
    376384                        }
    377385                        att_val_end = AbsPos();
    378386                        Advance(1);
    379                         if (at_xmlns<ASCII>(cur())) {
     387                        if (at_xmlns<C>(cur()+att_name_start-AbsPos())) {
    380388                                Namespace_action(att_name_start, att_name_end,
    381389                                                 att_val_start, att_val_end);
     
    386394                        }
    387395                        /* Now check for end or repeat. Avoid whitespace scan if possible.*/
    388                         if (AtChar<ASCII,'>'>(cur())) {
     396                        if (AtChar<C,'>'>(cur())) {
    389397                                Advance(1);
    390398                                StartTag_action(markup_start, AbsPos());
    391399                                break;
    392400                        }
    393                         else if (at_EmptyElementDelim<ASCII>(cur())) {
     401                        else if (at_EmptyElementDelim<C>(cur())) {
    394402                                Advance(2);
    395403                                EmptyElement_action(markup_start, AbsPos());
     
    397405                        }
    398406                        ScanTo(NonWS);
    399                         if (AtChar<ASCII,'>'>(cur())) {
     407                        if (AtChar<C,'>'>(cur())) {
    400408                                Advance(1);
    401409                                StartTag_action(markup_start, AbsPos());
    402410                                break;
    403411                        }
    404                         else if (at_EmptyElementDelim<ASCII>(cur())) {
     412                        else if (at_EmptyElementDelim<C>(cur())) {
    405413                                Advance(2);
    406414                                EmptyElement_action(markup_start, AbsPos());
     
    417425
    418426
    419 inline void ParsingEngine::ParseContent () {
     427template <CodeUnit_Base C>
     428inline void ParsingEngine<C>::ParseContent() {
    420429
    421430        int text_start = AbsPos();
    422431        do {
    423432                ScanTo(MarkupStart); /* '<', '&', or ']' for ']]>' test */
    424 /*              if (AtChar<ASCII,'<'>(cur())) {
    425                         if (AbsPos() > text_start) Text_action(text_start, AbsPos());
    426                         Parse_Markup();
     433/*              if (AtChar<C,'<'>(cur())) {
     434                        if (AbsPos() > text_start) Text_action(text_start, AbsPos());
     435                        Parse_Markup<C>();
    427436                }*/
    428437                int markup_start = AbsPos();
    429                 if (at_ElementTag_Start<ASCII>(cur())) {
     438                if (at_ElementTag_Start<C>(cur())) {
    430439                        if (AbsPos() > text_start) Text_action(text_start, AbsPos());
    431440                        Parse_StartTag();
    432441                }
    433                 else if (at_EndTag_Start<ASCII>(cur())) {
     442                else if (at_EndTag_Start<C>(cur())) {
    434443                        if (AbsPos() > text_start) Text_action(text_start, AbsPos());
    435444                        Parse_EndTag();
    436445                }
    437                 else if (at_Comment_Start<ASCII>(cur())) {
     446                else if (at_Comment_Start<C>(cur())) {
    438447                        if (AbsPos() > text_start) Text_action(text_start, AbsPos());
    439448                        Parse_Comment();
    440449                }
    441                 else if (AtChar<ASCII,'&'>(cur())) {
     450                else if (AtChar<C,'&'>(cur())) {
    442451                        if (AbsPos() > text_start) Text_action(text_start, AbsPos());
    443452                        Parse_Reference();
    444453                }
    445                 else if (at_CDATA_Start<ASCII>(cur())) {
     454                else if (at_CDATA_Start<C>(cur())) {
    446455                        if (AbsPos() > text_start) Text_action(text_start, AbsPos());
    447456                        Parse_CDATA();
    448457                }
    449                 else if (at_PI_Start<ASCII>(cur())) {
     458                else if (at_PI_Start<C>(cur())) {
    450459                        if (AbsPos() > text_start) Text_action(text_start, AbsPos());
    451460                        Parse_PI();
    452461                }
    453                 else if (at_CDATA_End<ASCII>(cur())) {
     462                else if (at_CDATA_End<C>(cur())) {
    454463                        if (AbsPos() > text_start) Text_action(text_start, AbsPos());
    455464                        Advance(3);
     
    476485}
    477486
    478 //
    479 // The following does not yet validate the syntax of EncNames.
    480 // EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
    481 // Future approach: first use lookup in EncNameTable,
    482 //           if not found, do case convert, try again,
    483 //             (avoids cost of case convert normally)
    484 //           if not found, validate syntax of EncNames,
    485 //           report error or EncName unknown.
    486 //
    487 void ParsingEngine::ReadXmlInfo(Entity_Declaration_Info& xml_info) {
    488   int BOM = lex->BOM_size(0);
    489   xml_info.has_ByteOrderMark = BOM > 0;
    490   xml_info.has_version_decl = false;
    491   xml_info.has_encoding_decl = false;
    492   xml_info.has_standalone_decl = false;
    493   Advance(BOM);
    494   int decl_start = AbsPos();
    495   // It is possible that there is no XML declaration.
    496   if (!at_XmlDecl_start<ASCII>(cur())) return;
    497   // Otherwise, the XML declaration exists and must have
    498   // at least version information.
    499   xml_info.has_version_decl = true;
    500   Advance(6);
    501   ASCII_ScanTo(NonWS);
    502   if (!at_version<ASCII>(cur())) {Error_action(decl_start, AbsPos()); return;}
    503   Advance(7);
    504   ASCII_ScanTo(NonWS);
    505   if (!AtChar<ASCII,'='>(cur())) {Error_action(decl_start, AbsPos()); return;}
    506   Advance(1);
    507   ASCII_ScanTo(NonWS);
    508   if (at_1_0<ASCII>(cur())) xml_info.version = 0;
    509   else if (at_1_1<ASCII>(cur())) xml_info.version = 1;
    510   else {Error_action(decl_start, AbsPos()); return;}
    511   Advance(5);
    512   if (at_PI_End<ASCII>(cur())) {Advance(2); return;}
    513   if (!at_WhiteSpace<XML_1_0, ASCII>(cur())) {Error_action(decl_start, AbsPos()); return;}
    514   ASCII_ScanTo(NonWS);
    515   if (at_encoding<ASCII>(cur())) {
    516       xml_info.has_encoding_decl = true;
    517       Advance(8);
    518       ASCII_ScanTo(NonWS);
    519       if (!AtChar<ASCII,'='>(cur())) {Error_action(decl_start, AbsPos()); return;}
    520       Advance(1);
    521       ASCII_ScanTo(NonWS);
    522       xml_info.encoding_start_pos = AbsPos()+1;
    523       if (AtChar<ASCII,'"'>(cur())) {
    524         Advance(1);
    525         ASCII_ScanTo(DQuote);
    526         if (!AtChar<ASCII,'"'>(cur())) {Error_action(decl_start, AbsPos()); return;}
    527       }
    528       else if (AtChar<ASCII,'\''>(cur())) {
    529         Advance(1);
    530         ASCII_ScanTo(SQuote);
    531         if (!AtChar<ASCII,'\''>(cur())) {Error_action(decl_start, AbsPos()); return;}
    532       }
    533       else {Error_action(decl_start, AbsPos()); return;}
    534       xml_info.encoding_end_pos = AbsPos();
    535       Advance(1);
    536       if (at_PI_End<ASCII>(cur())) {Advance(2); return;}
    537       if (!at_WhiteSpace<XML_1_0, ASCII>(cur())) {Error_action(decl_start, AbsPos()); return;}
    538       ASCII_ScanTo(NonWS);
    539   }
    540   if (at_standalone<ASCII>(cur())) {
    541       xml_info.has_standalone_decl = true;
    542       Advance(10);
    543       ASCII_ScanTo(NonWS);
    544       if (!AtChar<ASCII,'='>(cur())) {Error_action(decl_start, AbsPos()); return;}
    545       Advance(1);
    546       ASCII_ScanTo(NonWS);
    547       if (at_yes<ASCII>(cur())) {Advance(5); xml_info.standalone = true;}
    548       else if (at_no<ASCII>(cur())) {Advance(4); xml_info.standalone = false;}
    549       else {Error_action(decl_start, AbsPos()); return;}
    550       ASCII_ScanTo(NonWS);
    551   }
    552   if (at_PI_End<ASCII>(cur())) {Advance(2); return;}
    553   else {Error_action(decl_start, AbsPos()); return;}
    554 }
    555 
    556 // Similar to reading the XML_declaration of the document entity,
    557 // ReadTextDeclaration reads the text declaration of an external
    558 // parsed entity.  This is not really needed at present, for DTDless
    559 // processing.
    560 void ParsingEngine::ReadTextDeclaration(Entity_Declaration_Info& xml_info) {
    561   int BOM = lex->BOM_size(0);
    562   xml_info.has_ByteOrderMark = BOM > 0;
    563   xml_info.has_version_decl = false;
    564   xml_info.has_encoding_decl = false;
    565   xml_info.has_standalone_decl = false;
    566   Advance(BOM);
    567   int decl_start = AbsPos();
    568   // It is possible that there is no XML declaration.
    569   if (!at_XmlDecl_start<ASCII>(cur())) return;
    570   // Otherwise, the text declaration exists and may have
    571   // version information.
    572   Advance(6);
    573   ASCII_ScanTo(NonWS);
    574   if (at_version<ASCII>(cur())) {
    575     xml_info.has_version_decl = true;
    576     Advance(7);
    577     ASCII_ScanTo(NonWS);
    578     if (!AtChar<ASCII,'='>(cur())) {Error_action(decl_start, AbsPos()); return;}
    579     Advance(1);
    580     ASCII_ScanTo(NonWS);
    581     if (at_1_0<ASCII>(cur())) xml_info.version = 0;
    582     else if (at_1_1<ASCII>(cur())) xml_info.version = 1;
    583     else {Error_action(decl_start, AbsPos()); return;}
    584     Advance(5);
    585     // Must have whitespace character before declaration.
    586     if (!at_WhiteSpace<XML_1_0, ASCII>(cur())) {Error_action(decl_start, AbsPos()); return;}
    587     ASCII_ScanTo(NonWS);
    588   }
    589   if (!at_encoding<ASCII>(cur())) {Error_action(decl_start, AbsPos()); return;}
    590   xml_info.has_encoding_decl = true;
    591   Advance(8);
    592   ASCII_ScanTo(NonWS);
    593   if (!AtChar<ASCII,'='>(cur())) {Error_action(decl_start, AbsPos()); return;}
    594   Advance(1);
    595   ASCII_ScanTo(NonWS);
    596   xml_info.encoding_start_pos = AbsPos()+1;
    597   if (AtChar<ASCII,'"'>(cur())) {
    598       Advance(1);
    599       ASCII_ScanTo(DQuote);
    600       if (!AtChar<ASCII,'"'>(cur())) {Error_action(decl_start, AbsPos()); return;}
    601   }
    602   else if (AtChar<ASCII,'\''>(cur())) {
    603       Advance(1);
    604       ASCII_ScanTo(SQuote);
    605       if (!AtChar<ASCII,'\''>(cur())) {Error_action(decl_start, AbsPos()); return;}
    606   }
    607   else {Error_action(decl_start, AbsPos()); return;}
    608   xml_info.encoding_end_pos = AbsPos();
    609   Advance(1);
    610   ASCII_ScanTo(NonWS);
    611   if (at_PI_End<ASCII>(cur())) {Advance(2); return;}
    612   else {Error_action(decl_start, AbsPos()); return;}
    613 }
  • trunk/src/engine.h

    r19 r37  
    99#define ENGINE_H
    1010
     11#include "xmlparam.h"
     12#include "xmlbuffer.h"
    1113#include "bitlex.h"
    12 
    13 // Information about the character set encoding, XML version and
    14 // standalone status of an XML entity.
    15 struct Entity_Declaration_Info
    16   {bool has_ByteOrderMark;
    17    bool has_version_decl;
    18    bool has_encoding_decl;
    19    bool has_standalone_decl;
    20    int version;
    21    int encoding_start_pos;
    22    int encoding_end_pos;
    23    bool standalone;
    24 };
    2514
    2615
     
    2817data.  */
    2918
    30   class ParsingEngine {
    31           public:
    32                   ParsingEngine(char * filename);
    33                   void ParseContent();
    34                   void InitLexer();
    35                   void ReadXmlInfo (Entity_Declaration_Info& xml_info);
    36                   void ReadTextDeclaration (Entity_Declaration_Info& xml_info);
    37           protected:
     19class Parser_Interface {
     20public:
     21        static Parser_Interface * ParserFactory(char * filename);
     22        virtual void ParseContent() = 0;
     23        unsigned char * GetCodeUnitPtr(int pos);
     24        bool has_ByteOrderMark();
     25        XML_version get_version();
     26        XML_standalone standalone_status();
     27        bool has_EncodingDecl();
     28        int get_Encoding_pos();
     29        int get_Encoding_lgth();
     30protected:
     31        /* Co-classes */
     32        Lexer_Interface * lexer;
     33        XML_Buffer_Interface * xml_buf;
     34        /* Parallel data streams for current buffer full of XML data. */
     35        BytePack * x8data;
     36        LexicalStreamSet * buf;
     37               
     38        int buffer_base_pos;
     39        int buffer_rel_pos;
     40        int buffer_limit_pos;
     41};
    3842
     43template <CodeUnit_Base C>
     44class ParsingEngine : public Parser_Interface {
     45public:
     46        ParsingEngine(XML_Buffer_Interface * b);
     47        void ParseContent();
     48protected:
    3949
    40                   /* Getters for current point/position information. */
    41                   int AbsPos() const;
    42                   int BufferRelPos() const;
    43                   unsigned char * cur() const;
     50        /* Getters for current point/position information. */
     51        int AbsPos() const;
     52        int BufferRelPos() const;
     53        unsigned char * cur() const;
    4454
    45                   bool at_EOF () const;
     55        bool at_EOF () const;
    4656
    47                   /* Mutators that advance the input. */
    48                   void Advance(int n);
    49                   void ASCII_ScanTo(int lex_item);
    50                   void ScanTo(int lex_item);
    51                   void AdvanceToNewBasePosn(int advance_amt);
     57        /* Mutators that advance the input. */
     58        void Advance(int n);
     59        void ScanTo(int lex_item);
    5260
    53                   /* Parsing routines. */
     61        /* Parsing routines. */
    5462
    55                   void Parse_Markup ();
    56                   void Parse_Comment ();
    57                   void Parse_StartTag ();
    58                   void Parse_EndTag ();
    59                   void Parse_CDATA ();
    60                   void Parse_PI ();
    61                   void Parse_Reference ();
     63        void Parse_Markup ();
     64        void Parse_Comment ();
     65        void Parse_StartTag ();
     66        void Parse_EndTag ();
     67        void Parse_CDATA ();
     68        void Parse_PI ();
     69        void Parse_Reference ();
    6270
    63                   /* Co-classes */
    64                   XML_Buffer *xml_buf;
    65                   Lexer *lex;
    66                
    67                   int buffer_base_pos;
    68                   int buffer_rel_pos;
    69                   int avail_code_units;
    70 
    71                  /* Parallel data streams for current buffer full of XML data. */
    72                   ParallelStreamSet buf;
    73 
    74   };
     71};
    7572
    7673
Note: See TracChangeset for help on using the changeset viewer.