gecko-dev/js/js2/xmlparser.cpp

205 lines
5.0 KiB
C++
Raw Normal View History

#include <assert.h>
#include "parser.h"
#include "world.h"
#include "xmlparser.h"
namespace JavaScript {
2000-10-18 23:55:47 +00:00
bool XMLTag::getValue(String &name, String **value)
{
AttributeList::iterator i = mAttributeList.find(name);
if (i == mAttributeList.end())
return false;
else {
2000-10-18 23:55:47 +00:00
*value = &i->second;
return true;
}
}
void XMLParser::syntaxError(const char *msg, uint backUp)
{
mReader.unget(backUp);
mReader.error(Exception::syntaxError, widenCString(msg), mReader.getPos());
}
void XMLParser::parseName(String &id)
{
char16 ch = mReader.peek();
CharInfo chi(ch);
if (isAlpha(chi)) {
mReader.beginRecording(id);
mReader.recordChar(mReader.get());
while (true) {
ch = mReader.peek();
CharInfo chi(ch);
if (isAlphanumeric(chi))
mReader.recordChar(mReader.get());
else
break;
}
mReader.endRecording();
}
else
syntaxError("Invalid name");
}
void XMLParser::parseWhiteSpace()
{
char16 ch = mReader.peek();
CharInfo chi(ch);
while (isSpace(chi)) {
ch = mReader.get();
if (isLineBreak(ch))
mReader.beginLine();
chi = CharInfo(mReader.peek());
}
}
void XMLParser::parseAttrValue(String &val)
{
char16 ch = mReader.get();
if (ch != '\"')
syntaxError("'\"' expected");
else {
mReader.beginRecording(val);
while (true) {
ch = mReader.get();
if (mReader.getEof(ch))
syntaxError("Unterminated value");
if (ch == '\"')
break;
mReader.recordChar(ch);
}
mReader.endRecording();
}
}
XMLTag *XMLParser::parseTag()
{
char16 ch;
XMLTag *tag = new XMLTag();
ch = mReader.peek();
if (ch == '/') {
tag->setEndTag();
mReader.get();
}
else {
if (ch == '!') {
mReader.get();
if (mReader.peek() != '-')
syntaxError("badly formed tag");
mReader.get();
if (mReader.peek() != '-')
syntaxError("badly formed tag");
mReader.get();
while (true) {
ch = mReader.get();
if (mReader.getEof(ch))
syntaxError("Unterminated comment tag");
if (ch == '-') {
ch = mReader.get();
if (mReader.getEof(ch))
syntaxError("Unterminated comment tag");
if (ch != '-')
mReader.unget();
else {
ch = mReader.get();
if (mReader.getEof(ch))
syntaxError("Unterminated comment tag");
if (ch != '>')
syntaxError("encountered '--' in comment");
break;
}
}
if (isLineBreak(ch))
mReader.beginLine();
}
tag->setComment();
return tag;
}
}
parseName(tag->name());
parseWhiteSpace();
CharInfo chi(mReader.peek());
while (isAlpha(chi)) {
String attrValue;
String attrName;
parseName(attrName);
if (mReader.peek() == '=') {
mReader.get();
parseAttrValue(attrValue);
}
tag->addAttribute(attrName, attrValue);
parseWhiteSpace();
chi = CharInfo(mReader.peek());
}
ch = mReader.get();
if (mReader.getEof(ch))
syntaxError("Unterminated tag");
if (ch == '/') {
tag->setEmpty();
ch = mReader.get();
}
if (ch != '>')
syntaxError("'>' expected");
return tag;
}
void XMLParser::parseTagBody(XMLNode *parent, XMLTag *startTag)
{
while (true) {
char16 ch = mReader.get();
while (ch != '<') {
if (mReader.getEof(ch))
syntaxError("Unterminated tag body");
parent->addToBody(ch);
ch = mReader.get();
}
XMLTag *tag = parseTag();
if (tag->isEndTag() && (tag->name().compare(startTag->name()) == 0))
break;
else {
XMLNode *child = new XMLNode(parent, tag);
if (!tag->isEmpty())
parseTagBody(child, tag);
}
}
}
XMLNode *XMLParser::parseDocument()
{
XMLNode *top = new XMLNode(NULL, new XMLTag(widenCString("TOP")));
char16 ch = mReader.get();
while (ch == '<') {
XMLTag *tag = parseTag();
XMLNode *n = new XMLNode(top, tag);
if (!tag->isEmpty()) {
parseTagBody(n, tag);
}
parseWhiteSpace();
ch = mReader.get();
if (mReader.getEof(ch))
break;
}
return top;
}
Formatter& operator<<(Formatter& f, const XMLTag& tag)
{
tag.print(f);
return f;
}
Formatter& operator<<(Formatter& f, const XMLNode& node)
{
node.print(f);
return f;
}
} /* namespace JavaScript */