Thread: Some parsers
View Single Post
  #24  
Old 05-02-2008, 09:25 AM
Chompy Chompy is offline
¯\(º_o)/¯
Chompy's Avatar
Join Date: Sep 2006
Location: Norway
Posts: 2,815
Chompy is just really niceChompy is just really niceChompy is just really nice
Send a message via MSN to Chompy
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.line.tokenize(" ");
      
elements.add(t[1]);
      if (
elements.size() == 1) {
        if (
line.ends("?)>")) {
          
temp.data t[2].substring(1t[2].length()-3);
          for(
temp.var : data) {
            
vars.add(var);
            if (var.
ends("?")) {
              
optional.add(var);
            }
          }
          
vars2 vars;
        }
      }else{
        
temp.end t[2].substring(0t[2].length()-1);
        if (!
doctype_end) break;
        if (
end == "(#PCDATA)") {
          if (
t[1in 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.line.substring(1line.pos(">")-1);
          
temp.v2 line.substring(line.pos(">")+1);
               
v2 v2.substring(0v2.pos("<"));
          if (
line.starts("<"@">") && line.ends("</"@">")) {
            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.vars2) {
    
temp.a;
    if (
b.ends("?")) a.substring(0a.length()-1);
    if (
compiled.index(b) < 0) {
      
check.add(b);
    }
  }
  if (
check.size() > 0) {
    for(
temp.check) {
      if (
optional.index(c@"?") < 0) {
        echo(
"Variable '"@"' 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
__________________

Last edited by Chompy; 05-02-2008 at 02:22 PM..
Reply With Quote