Thrown by sdl parse functions when invalid SDL is encountered.
Used in SdlParseException to distinguish specific sdl parse errors.
A convenience function to parse a single tag. Calls tag.resetForNewSdl and then calls parseSdlTag.
Parses one SDL tag (not including its children) from sdlText saving slices for every name/value/attribute to the given tag struct. This function assumes that sdlText contains at least one full SDL _tag. The only time this function will allocate memory is if the value/attribute appenders in the tag struct are not large enough to hold all the values. Because of this, after the tag values/attributes are populated, it is up to the caller to copy any memory they wish to save unless sdlText is going to persist in memory. Note: this function does not handle the UTF-8 bom because it doesn't make sense to re-check for the BOM before every tag.
Converts literal to the given D type T. This is a wrapper arround the sdlLiteralToD function that returns true on sucess, except this function returns the value itself and throws an SdlParseException on error.
Converts literal to the given D type T. If isSomeString!T, then it will remove the surrounding quotes if they are present.
Holds three character arrays for an SDL attribute, namespace/id/value.
Assists in walking an SDL tree which supports the StAX method of parsing.
Contains a tag's name, values and attributes. It does not contain any information about its child tags because that part of the sdl would not have been parsed yet, however, it does indicate if the tag was followed by an open brace. This struct is used directly for the StAX/SAX APIs and indirectly for the DOM or Reflection APIs.
1 void printTags(char[] sdl) { 2 Tag tag; 3 while(parseSdlTag(&tag, &sdl)) { 4 writefln("(depth %s) tag '%s' values '%s' attributes '%s'", 5 tag.depth, tag.name, tag.values.data, tag.attributes.data); 6 } 7 } 8 9 struct Person { 10 string name; 11 ushort age; 12 string[] nicknames; 13 auto children = appender!(Person[])(); 14 void reset() { 15 name = null; 16 age = 0; 17 nicknames = null; 18 children.clear(); 19 } 20 void parseFromSdl(ref SdlWalker walker) { 21 tag.enforceNoValues(); 22 tag.enforceNoAttributes(); 23 reset(); 24 foreach(auto personWalker = walker.children(); 25 !personWalker.empty; personWalker.popFront) { 26 27 if(tag.name == "name") { 28 29 tag.enforceNoAttributes(); 30 tag.enforceNoChildren(); 31 tag.getOneValue(name); 32 33 } else if(tag.name == "age") { 34 35 tag.enforceNoAttributes(); 36 tag.enforceNoChildren(); 37 tag.getOneValue(age); 38 39 } else if(tag.name == "nicknames") { 40 41 tag.enforceNoAttributes(); 42 tag.enforceNoChildren(); 43 tag.getValues(nicknames); 44 45 } else if(tag.name == "child") { 46 47 48 49 // todo implement 50 51 } else tag.throwIsUnknown(); 52 } 53 } 54 void validate() { 55 if(name == null) throw new Exception("person is missing the 'name' tag"); 56 if(age == 0) throw new Exception("person is missing the 'age' tag"); 57 } 58 } 59 60 void parseTags(char[] sdl) { 61 struct Person { 62 string name; 63 ushort age; 64 string[] nicknames; 65 Person[] children; 66 void reset() { 67 name = null; 68 age = 0; 69 nicknames = null; 70 children = null; 71 } 72 void validate() { 73 if(name == null) throw new Exception("person is missing the 'name' tag"); 74 if(age == 0) throw new Exception("person is missing the 'age' tag"); 75 } 76 } 77 auto people = appender(Person[])(); 78 Person person; 79 80 Tag tag; 81 for(auto walker = SdlWalker(&tag, sdl); !walker.empty; walker.popFront) { 82 if(tag.name == "person") { 83 84 tag.enforceNoValues(); 85 tag.enforceNoAttributes(); 86 person.reset(); 87 person.validate(); 88 people.put(person); 89 90 } else tag.throwIsUnknown(); 91 } 92 }
TODO: implement escaped strings TODO: finish unit tests TODO: write a input-range sdl parser TODO: implement datetime/timespans
use freely for any purpose
An SDL (Simple Declarative Language) parser. Supports StAX/SAX style API. See more.std.dom for DOM style API.