Changeset 56
- Timestamp:
- 09/11/07 11:02:42 (5 years ago)
- Files:
-
- trunk/dparser/dparse.d (modified) (20 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/dparser/dparse.d
r53 r56 61 61 Value v = cast(Value)set.Parser(a); 62 62 63 assert(v !is null );63 assert(v !is null,"ERR0R"); 64 64 writef("%d\n", v.value); 65 65 } … … 123 123 abstract class PObject 124 124 { 125 bool fail();125 abstract bool fail(); 126 126 } 127 127 … … 194 194 /** 195 195 */ 196 class PObjectBox(T ) : PObjectBoxBase196 class PObjectBox(T,bool str = true) : PObjectBoxBase 197 197 { 198 198 T t; … … 206 206 char[] string() 207 207 { 208 static if(is(T == char[])) 209 return t; 208 static if(str) 209 { 210 static if(is(T == char[])) 211 return t; 212 else 213 return ToString(t); 214 } 210 215 else 211 return std.string.toString(t);216 return "<<"~T.stringof~">>"; 212 217 } 213 218 } 214 219 //typedef PObjectVector!(5) Five; 220 221 /** 222 */ 223 class PObjectList(T) : PObject 224 { 225 T[] list; 226 int at=0; 227 228 this(){ list = null; } 229 230 this(T ti) 231 { 232 static if(is(T :Object)) assert(ti !is null); 233 list = new T[5]; 234 list[at] = ti; 235 at++; 236 237 } 238 239 /// Add a T 240 uint Add(T ti) 241 { 242 static if(is(T :Object)) assert(ti !is null); 243 if(list.length <= at) list.length = at + 5; 244 list[at] = ti; 245 at++; 246 return at-1; 247 } 248 249 /// return the number of items stored 250 uint Count(){return at;} 251 252 T[] get() 253 { 254 return list[0..at]; 255 } 256 257 bool fail() { return false; } 258 } 259 260 class PObjectListLeft(T) : PObjectList!(T) 261 { 262 this(T t){super(t);} 263 this(){} 264 265 /// Add a T 266 uint Add(T ti) 267 { 268 static if(is(T :Object)) assert(ti !is null); 269 270 if(list.length <= at) 271 { 272 auto t = list[$-at..$].dup; 273 list.length = at + 5; 274 list[$-at..$] = t; 275 } 276 list[$-1-at] = ti; 277 at++; 278 return at-1; 279 } 280 281 T[] get() 282 { 283 return list[$-at..$]; 284 } 285 } 286 287 unittest 288 { 289 writef("unittest@"__FILE__":"~itoa!(__LINE__)~\n); 290 291 auto o = new PObjectListLeft!(int); 292 o.Add(1); 293 o.Add(2); 294 o.Add(3); 295 o.Add(4); 296 o.Add(5); 297 o.Add(6); 298 299 assert(o.get == [6,5,4,3,2,1], "PObjectListLeft failed"); 300 } 215 301 216 302 … … 219 305 A sub class of PObject that is used for repeated reductions 220 306 */ 221 class PObjectSet : PObject 222 { 223 PObject[] set; 224 this(){ set = null; } 225 226 /// Add a PObject 227 uint Add(PObject o) 228 { 229 uint ret = set.length; 230 set ~= o; 231 return ret; 232 } 233 234 /// return the number of items stored 235 uint Count(){return set.length;} 236 307 class PObjectSet : PObjectList!(PObject) 308 { 237 309 /// Discard some PObjects 238 310 void Back(uint b) 239 311 { 240 set.length = b; 241 } 242 243 bool fail() { return false; } 312 at = b; 313 } 244 314 } 245 315 … … 269 339 270 340 bool fail() { return true; } 341 } 342 343 class PObjectFill : PObject 344 { 345 bool b; 346 this(bool _b){b=_b;} 347 bool fail(){return b;} 271 348 } 272 349 … … 327 404 328 405 329 char[] ReduceWhite(char[] str)406 public char[] ReduceWhite(char[] str) 330 407 { 331 408 bool pass = true; … … 696 773 static const char[] Remaining = str[Used.length .. $]; 697 774 775 // Get a given rule 698 776 template Rule(char[] str) 699 777 { … … 750 828 const int Revert = i*(Places.max+1) + Places.Revert; 751 829 const int Start = i*(Places.max+1) + Places.Start; 752 // pragma(msg, ">> CaseLabel!("~itoa!(i)~") = { Back : "~itoa!(Back)~", Revert : "~itoa!(Revert)~", Start : "~itoa!(Start)~"}");830 // debug(dparse_verbose) pragma(msg, ">> CaseLabel!("~itoa!(i)~") = { Back : "~itoa!(Back)~", Revert : "~itoa!(Revert)~", Start : "~itoa!(Start)~"}"); 753 831 } 754 832 … … 760 838 SEQUENCE : ID SEQUENCE | ; 761 839 */ 762 debug int counter = 0; 763 764 template Parser(char[] start, char[] rules) 840 debug(dParse_runtime) int counter = 0; 841 842 private struct Frame{uint pos; uint rule; uint count;} 843 844 template ParserT(char[] start, char[] rules) 765 845 { 766 846 private alias Parse_Grammar!(rules) grammar; 767 847 static assert(grammar.Match); 768 848 849 static if(grammar.Match && DropWhiteF(grammar.Remaining).length != 0) 850 pragma(msg, "Unparsed data: "~DropWhiteF(grammar.Remaining)); 851 769 852 PObject Rule(char[] ruleIs)(IParser p) 770 853 { 771 debug 854 debug(dParse_runtime) 772 855 { 773 856 int ind = counter++; 774 857 bool worked = false; 775 std.stdio.writef("Try\t(%d)%s...\n", ind, ruleIs); 776 } 777 debug scope(success) std.stdio.writef("Done\t(%d)%s %s\n", ind, ruleIs, worked); 778 debug scope(failure) std.stdio.writef("FAILED\t(%d)%s %s\n", ind, ruleIs, worked); 779 780 pragma(msg, "Seeking: "~ruleIs); 781 782 struct Frame{uint pos; uint rule; uint count;} 858 writef("Try\t(%d)%s...\n", ind, ruleIs); 859 } 860 debug(dParse_runtime) scope(success) writef("Done\t(%d)%s %s\n", ind, ruleIs, worked); 861 debug(dParse_runtime) scope(failure) writef("FAILED\t(%d)%s %s\n", ind, ruleIs, worked); 862 863 debug(dparse_verbose) pragma(msg, "Seeking: "~ruleIs); 864 783 865 Stack!(Frame) backups; 784 866 Frame store; … … 787 869 { 788 870 alias grammar.Rule!(ruleIs).Is rule; 789 pragma(msg,"Build: \""~rule.Name~"\"" );871 debug(dparse_verbose) pragma(msg,"Build: \""~rule.Name~"\"" ); 790 872 // record start location 791 873 uint start = p.pos; … … 794 876 caseLoop: foreach(ci,casev;rule.Disjuncts) 795 877 { 796 debug std.stdio.writef("*\t(%d)%s:%s...\n", ind, ruleIs,casev.Action);878 debug(dParse_runtime) writef("*\t(%d)%s:%s...\n", ind, ruleIs,casev.Action); 797 879 798 880 // dump all checkpoints … … 800 882 801 883 // return to start location 802 p.pos = start; 884 static if(ci != 0) 885 { 886 debug(dParse_runtime) writef("backing\t (%d):%d\n", ind ,start); 887 p.pos = start; 888 } 803 889 804 890 // allocate storage for returns … … 807 893 static assert(count == temps.length); 808 894 809 // pragma(msg, "ICE from "~rule.name); 810 pragma(msg, "\tfor \""~rule.Name~"\" doing case #"~itoa!(ci)~" action = \""~casev.Action~"\", length = "~itoa!(count)); 895 debug(dparse_verbose) pragma(msg, "\tfor \""~rule.Name~"\" doing case #"~itoa!(ci)~" action = \""~casev.Action~"\", length = "~itoa!(count)); 811 896 812 897 static const int FirstCase = -1; … … 823 908 foreach(index, cl; casev.Clauses) 824 909 { 910 static if(/*ci == 0 &&*/ index == 0 && ruleIs == cl.Text) pragma(msg, "Directly recursive rule: "~ruleIs) 825 911 // static stuff 826 912 827 debug std.stdio.writef("Attemping clause %s (%d)...\n", cl.Text, index);828 829 pragma(msg, "\t\tgenerating clause: \""~cl.Text~"\" ("~itoa!(index)~")");913 debug(dParse_runtime) writef("Attemping clause %s (%d)...\n", cl.Text, index); 914 915 debug(dparse_verbose) pragma(msg, "\t\tgenerating clause: \""~cl.Text~"\" ("~itoa!(index)~")"); 830 916 831 917 static if(cl.Type != ItemType.single) … … 841 927 // for cases where empty match is not allowed 842 928 // get one 843 pragma(msg, "\t\t\t recurse in from \""~ruleIs~"\" on \""~cl.Text~\"\n);929 debug(dparse_verbose) pragma(msg, "\t\t\t recurse in from \""~ruleIs~"\" on \""~cl.Text~\"\n); 844 930 auto tmpStore1 = Rule!(cl.Text)(p); 845 pragma(msg, "\n\t\t\t recurse out from \""~ruleIs~"\" on \""~cl.Text~\");931 debug(dparse_verbose) pragma(msg, "\n\t\t\t recurse out from \""~ruleIs~"\" on \""~cl.Text~\"); 846 932 847 933 // test it … … 884 970 store.count = (cast(PObjectSet)temps[index]).Count(); 885 971 886 pragma(msg, "\t\t\trecurse in from \""~ruleIs~"\" on \""~cl.Text~\"\n);972 debug(dparse_verbose) pragma(msg, "\t\t\trecurse in from \""~ruleIs~"\" on \""~cl.Text~\"\n); 887 973 auto tmpStore2 = Rule!(cl.Text)(p); 888 pragma(msg, "\n\t\t\trecurse out from \""~ruleIs~"\" on \""~cl.Text~\");974 debug(dparse_verbose) pragma(msg, "\n\t\t\trecurse out from \""~ruleIs~"\" on \""~cl.Text~\"); 889 975 890 976 if(!tmpStore2.fail()) … … 909 995 } 910 996 } 911 pragma(msg,"\tdoing Action \""~casev.Action~\"); 912 return this.Action!(casev.Action)(temps); 997 debug(dparse_verbose) pragma(msg,"\tdoing Action \""~casev.Action~\"); 998 debug(dParse_runtime) writef("\treturn (%d)Act '%s'\"", ind, casev.Action); 999 1000 return Action!(casev.Action)(temps); 913 1001 } 914 915 return new PObjectFail("Failed while looking for "~ruleIs~\n);// pragma(msg, ">>"__FILE__":"~itoa!(__LINE__)~": is this right?"); 1002 debug(dParse_runtime) writef("Return (%d)failed\n", ind); 1003 1004 return new PObjectFail("Failed while looking for "~ruleIs~\n); 916 1005 } 917 1006 else 918 1007 { 919 pragma(msg, \"~ruleIs~"\" must be a terminal looking for it...");920 debug std.stdio.writef("T\t(%d)%s...\n", ind, ruleIs);921 // static assert(is(Terminal!(ruleIs)),"Terminal \""~ruleIs~"\" not found"); 1008 debug(dparse_verbose) pragma(msg, \"~ruleIs~"\" must be a terminal looking for it..."); 1009 debug(dParse_runtime) writef("T\t(%d)%s...\n", ind, ruleIs); 1010 922 1011 auto ret = Terminal!(ruleIs)(p); 923 1012 assert(ret !is null); 924 debug worked = !ret.fail; 1013 debug(dParse_runtime) worked = !ret.fail; 1014 1015 debug(dParse_runtime) writef("Return (%d)terminal\n", ind); 925 1016 return ret; 926 1017 } 927 1018 928 pragma(msg, "Done: "~ruleIs);1019 debug(dparse_verbose) pragma(msg, "Done: "~ruleIs); 929 1020 } 930 1021 alias Rule!(start) Parser; … … 976 1067 unittest // unittest Stack!(T) 977 1068 { 1069 writef("unittest@"__FILE__":"~itoa!(__LINE__)~"!("~T.stringof~")\n"); 1070 978 1071 Stack!(int) st; 979 1072 int i; … … 997 1090 } 998 1091 999 // Unittest code 1000 unittest 1001 { 1002 P p; 1003 data d = new data; 1004 char[][] pass = 1005 [ 1006 "BB"[], //root > next baz > (baz) baz) 1007 "HOB", //root > next baz > (owl* horse owl) baz > (() horse owl) baz 1008 "OHOB", //root > next baz > (owl* horse owl) baz > ((owl) horse owl) baz 1009 "OOHOB", //root > next baz > (owl* horse owl) baz > ((owl owl) horse owl) baz 1010 "BHO", //root > baz horse owl 1011 "CHB", //root > cat horse+ owl* baz > cat (horse) () baz 1012 "CHOB", //root > cat horse+ owl* baz > cat (horse) (owl) baz 1013 "CHHOB", //root > cat horse+ owl* baz > cat (horse horse) (owl) baz 1014 "CCC", //root > cat* cat cat > (cat) cat cat 1015 "KQKQKQKQQKQK", // root > twin* car > (twin twin twin) (car) > ((king qween) (king qween) (king qween)) (king qween qween king) 1016 ], 1017 fail = 1018 [ 1019 "BHHO"[], 1020 "COB", 1021 "CB", 1022 "CHHOOB", 1023 ]; 1024 1025 foreach(char[] passTest; pass) 1026 { 1027 d.dat = passTest; 1028 d.i=0; 1029 assert(!p.Parser(d).fail, \"~passTest~"\" failed to parse"); 1030 } 1031 1032 foreach(char[] failTest; fail) 1033 { 1034 d.dat = failTest; 1035 d.i=0; 1036 assert(p.Parser(d).fail, \"~failTest~"\" failed to fail to parse"); 1037 } 1038 } 1039 1040 struct P 1041 { 1042 PObject Terminal(char[] str : "baz")(IParser i) {data d = cast(data)i; if(d.i >= d.dat.length || d.dat[d.i] != 'B') return new PObjectFail; d.i++; return new PObjectBox!(char)('B');} 1043 PObject Terminal(char[] str : "owl")(IParser i) {data d = cast(data)i; if(d.i >= d.dat.length || d.dat[d.i] != 'O') return new PObjectFail; d.i++; return new PObjectBox!(char)('O');} 1044 PObject Terminal(char[] str : "horse")(IParser i) {data d = cast(data)i; if(d.i >= d.dat.length || d.dat[d.i] != 'H') return new PObjectFail; d.i++; return new PObjectBox!(char)('H');} 1045 PObject Terminal(char[] str : "cat")(IParser i) {data d = cast(data)i; if(d.i >= d.dat.length || d.dat[d.i] != 'C') return new PObjectFail; d.i++; return new PObjectBox!(char)('C');} 1046 PObject Terminal(char[] str : "king")(IParser i) {data d = cast(data)i; if(d.i >= d.dat.length || d.dat[d.i] != 'K') return new PObjectFail; d.i++; return new PObjectBox!(char)('K');} 1047 PObject Terminal(char[] str : "qween")(IParser i) {data d = cast(data)i; if(d.i >= d.dat.length || d.dat[d.i] != 'Q') return new PObjectFail; d.i++; return new PObjectBox!(char)('Q');} 1048 1049 PObject Action(char[] str : "bar") (PObject[1] i){return new PObjectVector!(1)(i);} 1050 PObject Action(char[] str : "beer")(PObject[2] i){return new PObjectVector!(2)(i);} 1051 PObject Action(char[] str : "pig") (PObject[3] i){return new PObjectVector!(3)(i);} 1052 PObject Action(char[] str : "keg") (PObject[4] i){return new PObjectVector!(4)(i);} 1053 1054 const char[] gram = " 1055 next : 1056 bar / baz | 1057 pig / owl * horse owl ; 1058 root : 1059 beer / next baz | 1060 pig / baz horse owl | 1061 keg / cat horse+ owl? baz | 1062 pig / cat* cat cat | 1063 beer / twin * car; 1064 twin : 1065 beer / king qween* ; 1066 car : 1067 keg / king qween qween king; 1068 "; 1069 1070 pragma(msg, ReduceWhite(gram)); 1071 1072 mixin Parser!("root",ReduceWhite(gram)); 1073 } 1074 1075 class data : IParser 1076 { 1077 char[] dat; 1078 uint i =0; 1079 uint pos() {return i;} 1080 void pos(uint j){ i = j;} 1081 } 1092 debug(dparse_unittest) 1093 { 1094 // Unittest code 1095 unittest 1096 { 1097 writef("unittest@"__FILE__":"~itoa!(__LINE__)~\n); 1098 1099 P p; 1100 data d = new data; 1101 char[][] pass = 1102 [ 1103 "BB"[], //root > next baz > (baz) baz) 1104 "HOB", //root > next baz > (owl* horse owl) baz > (() horse owl) baz 1105 "OHOB", //root > next baz > (owl* horse owl) baz > ((owl) horse owl) baz 1106 "OOHOB", //root > next baz > (owl* horse owl) baz > ((owl owl) horse owl) baz 1107 "BHO", //root > baz horse owl 1108 "CHB", //root > cat horse+ owl* baz > cat (horse) () baz 1109 "CHOB", //root > cat horse+ owl* baz > cat (horse) (owl) baz 1110 "CHHOB", //root > cat horse+ owl* baz > cat (horse horse) (owl) baz 1111 "CCC", //root > cat* cat cat > (cat) cat cat 1112 "KQKQKQKQQKQK", // root > twin* car > (twin twin twin) (car) > ((king qween) (king qween) (king qween)) (king qween qween king) 1113 ], 1114 fail = 1115 [ 1116 "BHHO"[], 1117 "COB", 1118 "CB", 1119 "CHHOOB", 1120 ]; 1121 1122 foreach(char[] passTest; pass) 1123 { 1124 d.dat = passTest; 1125 d.i=0; 1126 assert(!p.Parser(d).fail, \"~passTest~"\" failed to parse"); 1127 } 1128 1129 foreach(char[] failTest; fail) 1130 { 1131 d.dat = failTest; 1132 d.i=0; 1133 assert(p.Parser(d).fail, \"~failTest~"\" failed to fail to parse"); 1134 } 1135 } 1136 1137 struct P 1138 { 1139 PObject Terminal(char[] str : "baz")(IParser i) {data d = cast(data)i; if(d.i >= d.dat.length || d.dat[d.i] != 'B') return new PObjectFail; d.i++; return new PObjectBox!(char)('B');} 1140 PObject Terminal(char[] str : "owl")(IParser i) {data d = cast(data)i; if(d.i >= d.dat.length || d.dat[d.i] != 'O') return new PObjectFail; d.i++; return new PObjectBox!(char)('O');} 1141 PObject Terminal(char[] str : "horse")(IParser i) {data d = cast(data)i; if(d.i >= d.dat.length || d.dat[d.i] != 'H') return new PObjectFail; d.i++; return new PObjectBox!(char)('H');} 1142 PObject Terminal(char[] str : "cat")(IParser i) {data d = cast(data)i; if(d.i >= d.dat.length || d.dat[d.i] != 'C') return new PObjectFail; d.i++; return new PObjectBox!(char)('C');} 1143 PObject Terminal(char[] str : "king")(IParser i) {data d = cast(data)i; if(d.i >= d.dat.length || d.dat[d.i] != 'K') return new PObjectFail; d.i++; return new PObjectBox!(char)('K');} 1144 PObject Terminal(char[] str : "qween")(IParser i) {data d = cast(data)i; if(d.i >= d.dat.length || d.dat[d.i] != 'Q') return new PObjectFail; d.i++; return new PObjectBox!(char)('Q');} 1145 1146 PObject Action(char[] str : "bar") (PObject[1] i){return new PObjectVector!(1)(i);} 1147 PObject Action(char[] str : "beer")(PObject[2] i){return new PObjectVector!(2)(i);} 1148 PObject Action(char[] str : "pig") (PObject[3] i){return new PObjectVector!(3)(i);} 1149 PObject Action(char[] str : "keg") (PObject[4] i){return new PObjectVector!(4)(i);} 1150 1151 const char[] gram = " 1152 next : 1153 bar / baz | 1154 pig / owl * horse owl ; 1155 root : 1156 beer / next baz | 1157 pig / baz horse owl | 1158 keg / cat horse+ owl? baz | 1159 pig / cat* cat cat | 1160 beer / twin * car; 1161 twin : 1162 beer / king qween* ; 1163 car : 1164 keg / king qween qween king; 1165 "; 1166 1167 debug(dparse_verbose) pragma(msg, ReduceWhite(gram)); 1168 1169 mixin Parser!("root",ReduceWhite(gram)); 1170 } 1171 1172 class data : IParser 1173 { 1174 char[] dat; 1175 uint i =0; 1176 uint pos() {return i;} 1177 void pos(uint j){ i = j;} 1178 } 1179 }
