Changeset 108 for trunk/src


Ignore:
Timestamp:
Apr 24, 2008, 4:42:57 PM (11 years ago)
Author:
lindanl
Message:
 
Location:
trunk/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/contentmodel.h

    r106 r108  
    99#define CONTENTMODEL_H_
    1010
    11 #include <set>
    1211#include <iostream>
    1312#include <string>
     
    2928public:
    3029        CM_Any();
    31         int Set_IDs(int base_ID);
    32         void Set_First_Map();
    3330};
    3431
     
    3633public:
    3734        CM_Empty();
    38         int Set_IDs(int base_ID);
    39         void Set_First_Map();
    4035};
    4136
     
    4338public:
    4439        CM_Mixed();
    45         int Set_IDs(int base_ID);
    46         void Set_First_Map();
     40        symbol_set_t elements;
    4741};
    4842
  • trunk/src/engine.c

    r106 r108  
    635635        }
    636636        requireWS();
    637        
     637        int root_name_start = AbsPos();
    638638        ScanTo(NameFollow);
    639        
     639        char * s = copy_string(GetCodeUnitPtr(root_name_start),AbsPos()-root_name_start);
     640
    640641        old_abspos = AbsPos(); 
    641642    ScanTo(NonWS);
     
    660661        if (AtChar<C,'>'>(cur())){
    661662                Advance(1);   
    662                 Doctype_action(GetCodeUnitPtr(start_pos), LengthFrom(start_pos));
     663                int rootID = model_info->GlobalElementTable[s];
     664                CRE_Seq * rslt = new CRE_Seq;
     665                rslt->subCMs.push_back(new CRE_Name(rootID));
     666                CM_RegExp * cre = new CM_RegExp();
     667                cre->content_re = rslt;
     668               
     669               
     670                int id_count = cre->content_re->Set_IDs(0);
     671                cre->content_re->Set_First_Map();               
     672                symbol_set_t * transition_map = new symbol_set_t[id_count+1];
     673                cre->content_re->follow_map[0] = id_count+1;
     674               
     675                cre->content_re->Set_Follow_Map(transition_map);
     676                transition_map[0] = cre->content_re->first_map;
     677                if (cre->content_re->matches_empty)
     678                        transition_map[0][0]=id_count+1;
     679                       
     680                cre -> transition_map = transition_map;
     681               
     682                model_info->rootModel = cre;
    663683        }
    664684}
     
    770790        Advance(5);
    771791        cm = new CM_Empty();
     792        model_info->ContentModelData.push_back(cm);
    772793        }
    773794    else if (at_ANY<C>(cur())) {
    774795        Advance(3);
    775796        cm = new CM_Any();
     797        model_info->ContentModelData.push_back(cm);
    776798    }
    777799    else {
     
    779801                        Advance(1);
    780802                ScanTo(NonWS);
    781                 if (at_PCDATA<C>(cur()))
     803                if (at_PCDATA<C>(cur())){
    782804                        cm = Parse_RemainingMixed();
     805                        model_info->ContentModelData.push_back(cm);
     806                }
    783807                else{
    784808
     
    791815                        cre->content_re->follow_map[0] = id_count+1;
    792816                       
    793                         cre->content_re->Set_Follow_Map(transition_map);                       
     817                        cre->content_re->Set_Follow_Map(transition_map);
     818                        transition_map[0] = cre->content_re->first_map;
     819                       
     820                        if (cre->content_re->matches_empty)
     821                                transition_map[0][0]=id_count+1;
     822                               
    794823                        cre -> transition_map = transition_map;
    795824                       
     
    817846        if (AtChar<C,'*'>(cur())) {
    818847                Advance(2);
    819                 return r;  /* Or ??? new CM_Star(r);*/
    820         }
     848                }
    821849                else {
    822850                        Advance(1);
    823                         return r;
    824851                }
    825852    }
     
    827854        ScanTo(NonWS);
    828855        int k = 0;
    829         while(!at_Para_star<C>(cur())){
    830                
    831                 if (AtChar<C,'|'>(cur())){
    832                                 Advance(1);
    833                                 ScanTo(NonWS);
    834                                 int name_start = AbsPos();
    835                                 ScanTo(NameFollow);
    836                                 int lgth = AbsPos() - name_start;
    837                                 char * s = copy_string(GetCodeUnitPtr(name_start),lgth);
    838                                 int elemID = model_info->GlobalElementTable[s];
    839                                 if(elemID==0)
    840                                         Validity_Error(vErr_elementvalid);
    841 //                              r->first_map[elemID] = ++k;
    842                                 ScanTo(NonWS);
    843                 }
     856        while (AtChar<C,'|'>(cur())){
     857                        Advance(1);
     858                        ScanTo(NonWS);
     859                        int name_start = AbsPos();
     860                        ScanTo(NameFollow);
     861                        int lgth = AbsPos() - name_start;
     862                        char * s = copy_string(GetCodeUnitPtr(name_start),lgth);
     863                        int elemID = model_info->GlobalElementTable[s];
     864                        if(elemID==0)
     865                                Validity_Error(vErr_elementvalid);
     866                        r->elements[elemID] = ++k;
     867                        ScanTo(NonWS);
     868                }
     869                if (at_Para_star<C>(cur())) Advance(2);
     870                else {
     871                        Syntax_Error(NT_Mixed);
     872                        exit(-1);
    844873        }
    845         Advance(2);
    846 //      return new CM_Star(r);
    847874    }
     875    return r;
    848876}
    849877
     
    15901618        ExtSubsetDecl_action(GetCodeUnitPtr(start_pos), LengthFrom(start_pos));
    15911619}
     1620
     1621       
     1622/* Parse a valid start or empty element tag. */
     1623template <CodeUnit_Base C>
     1624inline int ParsingEngine<C>::Parse_ValidStartTag (bool& is_emptyStartTag){
     1625        int att_name_start;
     1626        int att_val_start;
     1627        int att_name_end, att_val_end;
     1628        unsigned char quoteCh;
     1629        Advance(1);
     1630       
     1631        int name_start = AbsPos();
     1632        ScanTo(NameFollow);  /* Name delimiter: WS, "/" or ">" */
     1633        char * s = copy_string(GetCodeUnitPtr(name_start),AbsPos()-name_start);
     1634        int elemID = model_info->GlobalElementTable[s];
     1635       
     1636        ElementName_action(GetCodeUnitPtr(text_or_markup_start+1), LengthFrom(text_or_markup_start+1));
     1637        /* The following test optimizes the most common case of a
     1638        start tag with no attributes.  */
     1639        if (AtChar<C,'>'>(cur())) {
     1640                Advance(1);
     1641                StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
     1642        }
     1643        else {
     1644                ScanTo(NonWS);
     1645                if (AtChar<C,'>'>(cur())) {
     1646                        Advance(1);
     1647                        StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
     1648                }
     1649                else if (at_EmptyElementDelim<C>(cur())) {
     1650                        Advance(2);
     1651                        is_emptyStartTag = true;
     1652                        EmptyElement_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
     1653                }
     1654                else do {
     1655                        /* Must be an attribute-value pair or error. */
     1656                        att_name_start = AbsPos();
     1657                        ScanTo(NameFollow);
     1658                        att_name_end = AbsPos();
     1659                        int lgth = att_name_end-att_name_start;
     1660               
     1661                        int attID = model_info->getOrInsertGlobalAttName(GetCodeUnitPtr(att_name_start), lgth);
     1662                        if (attID >= LastAttOccurrence.size()) LastAttOccurrence.push_back(0);
     1663                        else {
     1664                                if (LastAttOccurrence[attID] > text_or_markup_start) {
     1665                                        WF_Error(wfErr_uniqattspec); /* Duplicate attribute. */
     1666                                        break;
     1667                                }                       
     1668                        }
     1669                        LastAttOccurrence[attID] = att_name_start;
     1670                        /* The following optimized tests handle the frequently occurring
     1671                        case that there are no blanks on either side of the equals sign.
     1672                        In many cases, the very first test handles 100% of actual
     1673                        attribute-value pairs encountered. */
     1674                        if (at_EqualsQuote<C>(cur())) Advance(1);
     1675                        else {
     1676                                ScanTo(NonWS);
     1677                                if (!AtChar<C,'='>(cur())) {
     1678                                        Syntax_Error(NT_STag);
     1679                                        break;
     1680                                }
     1681                                ScanTo(NonWS);
     1682                                if (!AtQuote<C>(cur())) {
     1683                                        Syntax_Error(NT_STag);
     1684                                        break;
     1685                                }
     1686                        }
     1687                        att_val_start = AbsPos()+1;
     1688                        Parse_AttValue();
     1689                        att_val_end = AbsPos()-1;
     1690                        if (at_xmlns<C>(cur()+att_name_start-AbsPos())) {
     1691                                Namespace_action(GetCodeUnitPtr(att_name_start), att_name_end - att_name_start,
     1692                                                 GetCodeUnitPtr(att_val_start), att_val_end - att_val_start);
     1693                        }
     1694                        else {
     1695                                AttributeValue_action(GetCodeUnitPtr(att_name_start), att_name_end - att_name_start,
     1696                                                 GetCodeUnitPtr(att_val_start), att_val_end - att_val_start);
     1697                        }
     1698                        /* Now check for end or repeat. Avoid whitespace scan if possible.*/
     1699                        if (AtChar<C,'>'>(cur())) {
     1700                                Advance(1);
     1701                                StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
     1702                                break;
     1703                        }
     1704                        else if (at_EmptyElementDelim<C>(cur())) {
     1705                                Advance(2);
     1706                                is_emptyStartTag = true;       
     1707                                EmptyElement_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
     1708                                break;
     1709                        }
     1710                        ScanTo(NonWS);
     1711                        if (AtChar<C,'>'>(cur())) {
     1712                                Advance(1);
     1713                                StartTag_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
     1714                                break;
     1715                        }
     1716                        else if (at_EmptyElementDelim<C>(cur())) {
     1717                                Advance(2);
     1718                                is_emptyStartTag = true;
     1719                                EmptyElement_action(GetCodeUnitPtr(text_or_markup_start), LengthFrom(text_or_markup_start));
     1720                                break;
     1721                        }
     1722                        else if (AbsPos() == att_val_end + 1) {
     1723                                /* No WS following att value */
     1724                                Syntax_Error(NT_STag);
     1725                                break;
     1726                        }
     1727                } while (1);
     1728        }
     1729        return elemID;
     1730}
     1731
     1732template <CodeUnit_Base C>
     1733inline int ParsingEngine<C>::Parse_ValidElement() {
     1734        bool is_emptyStartTag = false;
     1735        int elemID = Parse_ValidStartTag(is_emptyStartTag);
     1736#ifdef DEBUG
     1737        printf("Parse_ValidElement: elemID = %d, is_emptyStartTag=%i\n",elemID, is_emptyStartTag);
     1738#endif
     1739        ContentModel * cm = model_info->ContentModelData[elemID-1];
     1740        switch (cm->cm_type) {
     1741                case cm_Empty:
     1742                        if (!is_emptyStartTag) {
     1743                                if (at_EndTag_Start<C>(cur())) {
     1744                                        Parse_EndTag();
     1745                                }
     1746                                else {
     1747                                        printf("Error: Expecting EMPTY content.\n");
     1748                                        exit(-1);
     1749                                }
     1750                        }
     1751                        break;
     1752                case cm_Any:           
     1753                        if (!is_emptyStartTag) {
     1754                                Parse_AnyContent();
     1755                                Parse_EndTag();
     1756                        }
     1757                        break;
     1758                case cm_Mixed:         
     1759                        if (!is_emptyStartTag) {
     1760                                Parse_MixedContent(((CM_Mixed *) cm)->elements);
     1761                                Parse_EndTag();
     1762                        }
     1763                        break;
     1764                case cm_RegExp:
     1765                        CM_RegExp * cre = (CM_RegExp *) cm;
     1766                        int content_state = 0;
     1767                        if (!is_emptyStartTag) {
     1768                                content_state = Parse_ValidContent(cre);
     1769                                Parse_EndTag();                         
     1770                        }
     1771                        if (cre->transition_map[content_state][0]==0) {
     1772                                printf("Error in content model for elemID %i.\n", elemID);
     1773                                exit(-1);
     1774                        }
     1775        }
     1776        return elemID;
     1777}
     1778
     1779template <CodeUnit_Base C>
     1780inline int ParsingEngine<C>::Parse_ValidContent(CM_RegExp * cre) {
     1781        int cur_state = 0;
     1782        do {
     1783                ScanTo(NonWS);
     1784                /* If non-null report WS  WS_action()? */
     1785                if (at_EndTag_Start<C>(cur())) {
     1786                        break;
     1787                }
     1788                else if (at_ElementTag_Start<C>(cur())) {
     1789                        int elemID = Parse_ValidElement();
     1790#ifdef DEBUG
     1791                        printf("Content model state transition %i", cur_state);
     1792#endif
     1793                        cur_state = cre->transition_map[cur_state][elemID];
     1794#ifdef DEBUG
     1795                        printf("-> %i\n", cur_state);
     1796#endif
     1797                }
     1798                else if (at_Comment_Start<C>(cur())) {
     1799                        Parse_Comment();
     1800                }
     1801                else if (at_PI_Start<C>(cur())) {
     1802                        Parse_PI();
     1803                }
     1804                else if (AtChar<C,'&'>(cur())) {
     1805                        Parse_EntityRef();
     1806                }
     1807                else if (at_EOF()) {
     1808                        break;
     1809                }
     1810                else {
     1811                        printf("Error: Expecting Element Content.\n");
     1812                        exit(-1);
     1813                }
     1814        } while(1);
     1815        return cur_state;
     1816}
     1817
     1818
     1819template <CodeUnit_Base C>
     1820inline void ParsingEngine<C>::Parse_AnyContent() {
     1821        do {
     1822                text_or_markup_start = AbsPos();
     1823                ScanToMarkupStart(); /* '<', '&', or ']' for ']]>' test */
     1824/*              if (AtChar<C,'<'>(cur())) {
     1825                        text_if_nonnull_action();
     1826                        Parse_Markup<C>();
     1827                }*/
     1828                if (at_ElementTag_Start<C>(cur())) {
     1829                        text_if_nonnull_action();
     1830                        int elemID = Parse_ValidElement();
     1831                }
     1832                else if (at_EndTag_Start<C>(cur())) {
     1833                        text_if_nonnull_action();
     1834                        return;
     1835                }
     1836                else if (at_Comment_Start<C>(cur())) {
     1837                        text_if_nonnull_action();
     1838                        Parse_Comment();
     1839                }
     1840                else if (at_CharRef_Start<C>(cur())) {
     1841                        text_if_nonnull_action();
     1842                        Parse_CharRef();
     1843                }
     1844                else if (AtChar<C,'&'>(cur())) {
     1845                        text_if_nonnull_action();
     1846                        Parse_EntityRef();
     1847                }
     1848                else if (at_CDATA_Start<C>(cur())) {
     1849                        text_if_nonnull_action();
     1850                        Parse_CDATA();
     1851                }
     1852                else if (at_PI_Start<C>(cur())) {
     1853                        text_if_nonnull_action();
     1854                        Parse_PI();
     1855                }
     1856                else if (at_CDATA_End<C>(cur())) {
     1857                        text_if_nonnull_action();
     1858                        Advance(3);
     1859                        Syntax_Error(NT_CharData);
     1860                }
     1861                else if (at_EOF()) {
     1862                        text_if_nonnull_action();
     1863                        return;
     1864                }
     1865                else {
     1866                        Advance(1);
     1867                        continue;
     1868                }
     1869        } while (1);
     1870}
     1871template <CodeUnit_Base C>
     1872inline void ParsingEngine<C>::Parse_MixedContent(symbol_set_t elems) {
     1873        do {
     1874                text_or_markup_start = AbsPos();
     1875                ScanToMarkupStart(); /* '<', '&', or ']' for ']]>' test */
     1876/*              if (AtChar<C,'<'>(cur())) {
     1877                        text_if_nonnull_action();
     1878                        Parse_Markup<C>();
     1879                }*/
     1880                if (at_ElementTag_Start<C>(cur())) {
     1881                        text_if_nonnull_action();
     1882                        int elemID = Parse_ValidElement();
     1883                        if (elems[elemID] == 0) {
     1884                                printf("Error in mixed content: elemID %i unexpected.\n", elemID);
     1885                                exit(-1);
     1886                        }
     1887                }
     1888                else if (at_EndTag_Start<C>(cur())) {
     1889                        text_if_nonnull_action();
     1890                        return;
     1891                }
     1892                else if (at_Comment_Start<C>(cur())) {
     1893                        text_if_nonnull_action();
     1894                        Parse_Comment();
     1895                }
     1896                else if (at_CharRef_Start<C>(cur())) {
     1897                        text_if_nonnull_action();
     1898                        Parse_CharRef();
     1899                }
     1900                else if (AtChar<C,'&'>(cur())) {
     1901                        text_if_nonnull_action();
     1902                        Parse_EntityRef();
     1903                }
     1904                else if (at_CDATA_Start<C>(cur())) {
     1905                        text_if_nonnull_action();
     1906                        Parse_CDATA();
     1907                }
     1908                else if (at_PI_Start<C>(cur())) {
     1909                        text_if_nonnull_action();
     1910                        Parse_PI();
     1911                }
     1912                else if (at_CDATA_End<C>(cur())) {
     1913                        text_if_nonnull_action();
     1914                        Advance(3);
     1915                        Syntax_Error(NT_CharData);
     1916                }
     1917                else if (at_EOF()) {
     1918                        text_if_nonnull_action();
     1919                        return;
     1920                }
     1921                else {
     1922                        Advance(1);
     1923                        continue;
     1924                }
     1925        } while (1);
     1926}
     1927
     1928
     1929
     1930template <CodeUnit_Base C>
     1931inline void ParsingEngine<C>::Parse_DocumentContent() {
     1932        int final_state = Parse_ValidContent(model_info->rootModel);
     1933        if (model_info->rootModel->transition_map[final_state][0]==0) {
     1934                printf("Error in document content.\n");
     1935                exit(-1);
     1936        }
     1937}
     1938
  • trunk/src/engine.h

    r106 r108  
    2727        static Parser_Interface * ParserFactory(char * byte_buffer, int byte_count, Entity_Info * e, Model_Info * m);
    2828        virtual void ParseContent() = 0;
     29        virtual void Parse_DocumentContent() = 0;
    2930        virtual void Parse_ExtSubsetDecl() = 0;
    3031        virtual void Parse_Prolog() = 0;
     
    119120        char * Replace_CharRef();
    120121        void Parse_Prolog();
    121                
     122        void Parse_DocumentContent();
     123       
     124        int Parse_ValidElement();
     125        int Parse_ValidContent(CM_RegExp * cre);
     126        void Parse_AnyContent();
     127        void Parse_MixedContent(symbol_set_t elems);
     128       
     129        int Parse_ValidStartTag(bool& is_empty);
    122130               
    123131        /*Parsing routine for external entities*/
  • trunk/src/xmlmodel.h

    r106 r108  
    178178        int getOrInsertGlobalElement(unsigned char * elem_name, int lgth);
    179179        int getOrInsertGlobalAttName(unsigned char * att_name, int lgth);
     180        // rootModel is a content model for the document root, consisting
     181        // of a single occurrence of the element named in the DOCTYPE declaration.
     182        CM_RegExp * rootModel;
    180183        vector<ContentModel *> ContentModelData;
    181184       
Note: See TracChangeset for help on using the changeset viewer.