⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.java

📁 Mobile 应用程序使用 Java Micro Edition (Java ME) 平台
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
	// legalElementContext again.	if (!strict && stackElemName.equals("table") &&	    !elemName.equals("tr") && !elemName.equals("td") &&	    !elemName.equals("th") && !elemName.equals("caption")) {	    Element e = dtd.getElement("tr");	    TagElement t = makeTag(e, true);	    legalTagContext(t);	    startTag(t);	    error("start.missing", elem.getName());	    return legalElementContext(elem);	}	// They try to find a legal context by checking if the current	// tag is valid in an enclosing context.  If so	// close out the tags by outputing end tags and then	// insert the curent tag.  If the tags that are	// being closed out do not have an optional end tag	// specification in the DTD then an html error is	// reported.	//	if (!insertTag && stack.terminate() && (!strict || stack.elem.omitEnd())) {	    for (TagStack s = stack.next ; s != null ; s = s.next) {		if (s.advance(elem)) {		    while (stack != s) {			endTag(true);		    }		    return true;		}		if (!s.terminate() || (strict && !s.elem.omitEnd())) {		    break;		}	    }	}	// Check if we know what tag is expected next.	// If so insert the tag.  Report an error if the	// tag does not have its start tag spec in the DTD as optional.	//	Element next = stack.first();	if (next != null && (!strict || next.omitStart()) &&	   !(next==dtd.head && elem==dtd.pcdata) ) {	    // System.out.println("-- omitting start tag: " + next);	    TagElement t = makeTag(next, true);	    legalTagContext(t);	    startTag(t);	    if (!next.omitStart()) {		error("start.missing", elem.getName());	    }	    return legalElementContext(elem);	}	// Traverse the list of expected elements and determine if adding	// any of these elements would make for a legal context.	//	if (!strict) {	    ContentModel content = stack.contentModel();	    Vector elemVec = new Vector();	    if (content != null) {		content.getElements(elemVec);		for (Enumeration v = elemVec.elements(); v.hasMoreElements();) {		    Element e = (Element)v.nextElement();		    // Ensure that this element has not been included as		    // part of the exclusions in the DTD.		    //		    if (stack.excluded(e.getIndex())) {			continue;		    }		    boolean reqAtts = false;		    for (AttributeList a = e.getAttributes(); a != null ; a = a.next) {		        if (a.modifier == REQUIRED) {			    reqAtts = true;			    break;		        }		    }		    // Ensure that no tag that has required attributes		    // gets inserted.	            //		    if (reqAtts) {		        continue;		    }		    ContentModel m = e.getContent();		    if (m != null && m.first(elem)) {			// System.out.println("-- adding a legal tag: " + e);			TagElement t = makeTag(e, true);			legalTagContext(t);			startTag(t);			error("start.missing", e.getName());			return legalElementContext(elem);		    }		}	    }	}	// Check if the stack can be terminated.  If so add the appropriate	// end tag.  Report an error if the tag being ended does not have its	// end tag spec in the DTD as optional.	//	if (stack.terminate() && (stack.elem != dtd.body) && (!strict || stack.elem.omitEnd())) {	    // System.out.println("-- omitting end tag: " + stack.elem);	    if (!stack.elem.omitEnd()) {		error("end.missing", elem.getName());	    }	    endTag(true);	    return legalElementContext(elem);	}	// At this point we know that something is screwed up.	return false;    }    /**     * Create a legal context for a tag.     */    void legalTagContext(TagElement tag) throws ChangedCharSetException {	if (legalElementContext(tag.getElement())) {	    markFirstTime(tag.getElement());	    return;	}	// Avoid putting a block tag in a flow tag.	if (tag.breaksFlow() && (stack != null) && !stack.tag.breaksFlow()) {	    endTag(true);	    legalTagContext(tag);	    return;	}	// Avoid putting something wierd in the head of the document.	for (TagStack s = stack ; s != null ; s = s.next) {	    if (s.tag.getElement() == dtd.head) {		while (stack != s) {		    endTag(true);		}		endTag(true);		legalTagContext(tag);		return;	    }	}	// Everything failed	error("tag.unexpected", tag.getElement().getName());    }    /**     * Error context. Something went wrong, make sure we are in     * the document's body context     */    void errorContext() throws ChangedCharSetException {	for (; (stack != null) && (stack.tag.getElement() != dtd.body) ; stack = stack.next) {	    handleEndTag(stack.tag);	}	if (stack == null) {	    legalElementContext(dtd.body);	    startTag(makeTag(dtd.body, true));	}    }    /**     * Add a char to the string buffer.     */    void addString(int c) {	if (strpos  == str.length) {	    char newstr[] = new char[str.length + 128];	    System.arraycopy(str, 0, newstr, 0, str.length);	    str = newstr;	}	str[strpos++] = (char)c;    }    /**     * Get the string that's been accumulated.     */    String getString(int pos) {	char newStr[] = new char[strpos - pos];	System.arraycopy(str, pos, newStr, 0, strpos - pos);	strpos = pos;	return new String(newStr);    }    char[] getChars(int pos) {	char newStr[] = new char[strpos - pos];	System.arraycopy(str, pos, newStr, 0, strpos - pos);	strpos = pos;	return newStr;    }    char[] getChars(int pos, int endPos) {	char newStr[] = new char[endPos - pos];	System.arraycopy(str, pos, newStr, 0, endPos - pos);	// REMIND: it's not clear whether this version should set strpos or not	// strpos = pos;	return newStr;    }    void resetStrBuffer() {	strpos = 0;    }    int strIndexOf(char target) {	for (int i = 0; i < strpos; i++) {	    if (str[i] == target) {		return i;	    }	}	return -1;    }    /**     * Skip space.     * [5] 297:5     */    void skipSpace() throws IOException {	while (true) {	    switch (ch) {	      case '\n':		ln++;		ch = readCh();		lfCount++;		break;	      case '\r':		ln++;		if ((ch = readCh()) == '\n') {		    ch = readCh();		    crlfCount++;		}		else {		    crCount++;		}		break;	      case ' ':	      case '\t':		ch = readCh();		break;	      default:		return;	    }	}    }    /**     * Parse identifier. Uppercase characters are folded     * to lowercase when lower is true. Returns falsed if     * no identifier is found. [55] 346:17     */    boolean parseIdentifier(boolean lower) throws IOException {	switch (ch) {	  case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':	  case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':	  case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':	  case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':	  case 'Y': case 'Z':	    if (lower) {		ch = 'a' + (ch - 'A');	    }	  case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':	  case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':	  case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':	  case 's': case 't': case 'u': case 'v': case 'w': case 'x':	  case 'y': case 'z':	    break;	  default:	    return false;	}	while (true) {	    addString(ch);	    switch (ch = readCh()) {	      case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':	      case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':	      case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':	      case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':	      case 'Y': case 'Z':		if (lower) {		    ch = 'a' + (ch - 'A');		}	      case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':	      case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':	      case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':	      case 's': case 't': case 'u': case 'v': case 'w': case 'x':	      case 'y': case 'z':	      case '0': case '1': case '2': case '3': case '4':	      case '5': case '6': case '7': case '8': case '9':	      case '.': case '-':	      case '_': // not officially allowed		break;	      default:		return true;	    }	}    }    /**     * Parse an entity reference. [59] 350:17     */    private char[] parseEntityReference() throws IOException {	int pos = strpos;	if ((ch = readCh()) == '#') {            int n = 0;            ch = readCh();            if ((ch >= '0') && (ch <= '9') ||                    ch == 'x' || ch == 'X') {                if ((ch >= '0') && (ch <= '9')) {                    // parse decimal reference                    while ((ch >= '0') && (ch <= '9')) {                        n = (n * 10) + ch - '0';                        ch = readCh();                    }                } else {                    // parse hexadecimal reference                    ch = readCh();                    char lch = (char) Character.toLowerCase(ch);                    while ((lch >= '0') && (lch <= '9') ||                            (lch >= 'a') && (lch <= 'f')) {                        if (lch >= '0' && lch <= '9') {                            n = (n * 16) + lch - '0';                        } else {                            n = (n * 16) + lch - 'a' + 10;                        }                        ch = readCh();                        lch = (char) Character.toLowerCase(ch);                    }                }                switch (ch) {                    case '\n':                        ln++;                        ch = readCh();                        lfCount++;                        break;                    case '\r':                        ln++;                        if ((ch = readCh()) == '\n') {                            ch = readCh();                            crlfCount++;                        }                         else {                            crCount++;                        }                        break;                    case ';':                        ch = readCh();                        break;                }                char data[] = {mapNumericReference((char) n)};                return data;            }            addString('#');            if (!parseIdentifier(false)) {                error("ident.expected");                strpos = pos;                char data[] = {'&', '#'};                return data;            }	} else if (!parseIdentifier(false)) {	    char data[] = {'&'};	    return data;	}	switch (ch) {	  case '\n':	    ln++;	    ch = readCh();	    lfCount++;	    break;	  case '\r':	    ln++;	    if ((ch = readCh()) == '\n') {		ch = readCh();		crlfCount++;	    }	    else {		crCount++;	    }	    break;	  case ';':	    ch = readCh();	    break;	}	String nm = getString(pos);	Entity ent = dtd.getEntity(nm);	// entities are case sensitive - however if strict	// is false then we will try to make a match by	// converting the string to all lowercase.	//	if (!strict && (ent == null)) {	    ent = dtd.getEntity(nm.toLowerCase());	}	if ((ent == null) || !ent.isGeneral()) {	    if (nm.length() == 0) {		error("invalid.entref", nm);		return new char[0];	    }	    /* given that there is not a match restore the entity reference */	    String str = "&" + nm;	    char b[] = new char[str.length()];	    str.getChars(0, b.length, b, 0);	    return b;	}	return ent.getData();    }    /**     * Converts numeric character reference to Unicode character.     *     * Normally the code in a reference should be always converted     * to the Unicode character with the same code, but due to     * wide usage of Cp1252 charset most browsers map numeric references     * in the range 130-159 (which are control chars in Unicode set)     * to displayable characters with other codes.     *     * @param c the code of numeric character reference.     * @return the character corresponding to the reference code.     */    private char mapNumericReference(char c) {        if (c < 130 || c > 159) {            return c;        }        return cp1252Map[c - 130];    }    /**     * Parse a comment. [92] 391:7     */    void parseComment() throws IOException {	while (true) {	    int c = ch;	    switch (c) {	      case '-':		  /** Presuming that the start string of a comment "<!--" has		      already been parsed, the '-' character is valid only as		      part of a comment termination and further more it must		      be present in even numbers. Hence if strict is true, we		      presume the comment has been terminated and return.		      However if strict is false, then there is no even number		      requirement and this character can appear anywhere in the		      comment.  The parser reads on until it sees the following		      pattern: "-->" or "--!>".		   **/		if (!strict && (strpos != 0) && (str[strpos - 1] == '-')) {		    if ((ch = readCh()) == '>') {			return;		    }		    if (ch == '!') {			if ((ch = readCh()) == '>') {			    return;			} else {			    /* to account for extra read()'s that happened */			    addString('-');			    addString('!');			    continue;			}		    }		    break;		}		if ((ch = readCh()) == '-') {		    ch = readCh();		    if (strict || ch == '>') {			return;		    }		    if (ch == '!') {			if ((ch = readCh()) == '>') {			    return;			} else {			    /* to account for extra read()'s that happened */			    addString('-');			    addString('!');			    continue;			}		    }		    /* to account for the extra read() */		    addString('-');		}		break;	      case -1:		  handleEOFInComment();		  return;	      case '\n':		ln++;		ch = readCh();		lfCount++;		break;	      case '>':		ch = readCh();		break;	      case '\r':		ln++;		if ((ch = readCh()) == '\n') {		    ch = readCh();		    crlfCount++;		}		else {		    crCount++;		}		c = '\n';		break;	      default:		ch = readCh();		break;	    }	    addString(c);	}    }    /**     * Parse literal content. [46] 343:1 and [47] 344:1     */    void parseLiteral(boolean replace) throws IOException {	while (true) {	    int c = ch;	    switch (c) {	      case -1:		error("eof.literal", stack.elem.getName());		endTag(true);		return;	      case '>':		ch = readCh();		int i = textpos - (stack.elem.name.length() + 2), j = 0;		// match end tag		if ((i >= 0) && (text[i++] == '<') && (text[i] == '/')) {		    while ((++i < textpos) &&			   (Character.toLowerCase(text[i]) == stack.elem.name.charAt(j++)));		    if (i == textpos) {			textpos -= (stack.elem.name.length() + 2);			if ((textpos > 0) && (text[textpos-1] == '\n')) {			    textpos--;			}			endTag(false);			return;		    }		}		break;	      case '&':		char data[] = parseEntityReference();		if (textpos + data.length > text.length) {		    char newtext[] = new char[Math.max(textpos + data.length + 128, text.length * 2)];		    System.arraycopy(text, 0, newtext, 0, text.length);		    text = newtext;		}		System.arraycopy(data, 0, text, textpos, data.length);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -