Ok, well I figured to try to make a simple DTD parser *cough* pfa *cough*
Anyways, here's my try on it..
PHP Code:
/* Made by Chompy
DTD parser v1.0
Usage:
dtd_parse(arr[])
*/
public function dtd_parse(script) {
temp.object = 0;
object = new TStaticVar();
temp.error = false;
temp.directory = 0;
temp.elements = 0;
temp.vars = 0;
temp.vars2 = 0;
temp.compiled = 0;
temp.optional = 0;
temp.doctype_end = false;
for(temp.line : script) {
if (line.starts("<!DOCTYPE ")) {
if (line.ends("[")) {
doctype_end = true;
continue;
}else{
echo("Syntax error.");
error = true;
break;;
}
}else if (line.starts("<!ELEMENT ")) {
if (!doctype_end) break;
temp.t = line.tokenize(" ");
elements.add(t[1]);
if (elements.size() == 1) {
if (line.ends("?)>")) {
temp.data = t[2].substring(1, t[2].length()-3);
for(temp.var : data) {
vars.add(var);
if (var.ends("?")) {
optional.add(var);
}
}
vars2 = vars;
}
}else{
temp.end = t[2].substring(0, t[2].length()-1);
if (!doctype_end) break;
if (end == "(#PCDATA)") {
if (t[1] in vars || t[1]@"?" in vars) {
object.(@elements[0]).(@t[1]) = 0; // init
}else{
echo("Variables is not declared in the root element.");
error = true;
break;
}
}else{
echo("(#PCDATA) is at the moment the only type available.");
error = true;
break;
}
}
continue;
}else if (line == "]>") {
doctype_end = false;
continue;
}else if (line.starts("<") && line.ends(">")) {
if (line.starts("</")) {
if (line == "</"@ directory @">") {
directory = 0;
break;
}else{
echo("Odd ending of root element.");
error = true;
break;
}
}else{
temp.check = line.positions("<").size();
if (check == 1) {
if (line == "<"@ elements[0] @">") {
directory = elements[0];
object.(@elements[0]) = new TStaticVar();
continue;
}
}else{
temp.v = line.substring(1, line.pos(">")-1);
temp.v2 = line.substring(line.pos(">")+1);
v2 = v2.substring(0, v2.pos("<"));
if (line.starts("<"@ v @">") && line.ends("</"@ v @">")) {
if (v in vars || v@"?" in vars) {
object.(@directory).(@v) = v2;
compiled.add(v);
vars.remove(v);
vars.remove(v@"?");
}
}
}
}
}
}
temp.check = 0;
for(temp.a : vars2) {
temp.b = a;
if (b.ends("?")) b = a.substring(0, a.length()-1);
if (compiled.index(b) < 0) {
check.add(b);
}
}
if (check.size() > 0) {
for(temp.c : check) {
if (optional.index(c@"?") < 0) {
echo("Variable '"@ c @"' must have a value, terminating parent root.");
if (this.(@elements[0]) != NULL)
this.(@elements[0]).destroy();
error = true;
break;
}
}
}
if (error) return 0;
return object;
}
and here, an example
PHP Code:
function onCreated() {
// DTD
temp.script = {
"<!DOCTYPE note [",
"<!ELEMENT note (to,from,heading,body,signature?)>",
"<!ELEMENT to (#PCDATA)>",
"<!ELEMENT from (#PCDATA)>",
"<!ELEMENT heading (#PCDATA)>",
"<!ELEMENT body (#PCDATA)>",
"<!ELEMENT signature (#PCDATA)>",
"]>",
"<note>",
"<to>John</to>",
"<from>Alex</from>",
"<heading>Reminder</heading>",
"<body>Hi there John!</body>",
"<signature>Signed, Alexander</signature>",
"</note>"
};
temp.obj = dtd_parse(script);
echo(obj.note.to); // John
}
(BTW, PCDATA stands for "Parsed Character Data")
Atm it supports optional variables (The ? indicates that an element is optional).
The thing is, if you look at the line
<!ELEMENT note (to,from,heading,body,signature?)>, in the parenthesis, are the variables that will be declared. If the variable has a '?' behind it, then it's optional. If it does not have a '?' behind, it must be set inside the
<note> ... </note> declaration or it will return an error
Currently stuff it supports:
-Making variables optional
-Error and Syntax checking
At the moment it doesn't support sub roots (it doesn't support:
NPC Code:
<!DOCTYPE items [
<!ELEMENT items (item*)>
<!ELEMENT item (name,icon,price,description?)>
<!ELEMENT name (#DATA)>
<!ELEMENT icon (#DATA)>
<!ELEMENT price (#DATA)>
<!ELEMENT description (#DATA)>
]>
<items>
<item>
<name>Wooden Sword</name>
<icon>icon.png</icon>
<price>40</price>
</item>
</item>
<name>Ice Sword</name>
<icon>icon.png</icon>
<price>80</price>
</item>
</items>
yet since I haven't added support for multiple elements). I might add that later though.. if I get into editing this again..
Ang again, I dunno if this is a DTD parser at all or if it is any good.. so.. feedback would be nice :o