Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search

[REBOL] Re: A little parse help

From: lmecir:mbox:vol:cz at: 26-Aug-2001 1:39

> I have been implementing my own document language. The main difference > is that it is a natural language and the lack of this parsing feature is > making my work Extremely complicated. > > That is because I do not want to impose strict format structure... so I > do not know if the document writer is going to end his line right away > or if he wishes to continue on the same line or if he'll put a space or > two, or put a space just before the end of the line... > > Add to this the fact that the keywords themselves are plain english (or > any other language, in fact :-) and ARE allowed within the content > itself and it makes the parsing a little bit harder still! > > This parsing feature alone would have cut my development time in half at > least! >
here is my solution: cfunc: function [ {make a closure} [catch] spec [block!] body [block!] ] [locals in-new-context spec2 body2 i] [ locals: copy [] spec2: copy [[throw]] body2: reduce ['do 'func spec2 body] i: 1 repeat item spec [ if all [any-word? :item not set-word? :item] [ append locals to word! :item append spec2 reduce [to word! :item [any-type!]] append body2 reduce ['get/any 'pick 'locals i] i: i + 1 ] ] in-new-context: func [ {do body with locals in new context} [throw] locals ] body2 throw-on-error [ func spec reduce [:in-new-context locals] ] ] a-b: cfunc [ {Generate an A-B parse rule} a [block!] b [block!] /local finish ] [ [ [ b (finish: [to end skip]) | (finish: a) ] finish ] ] comment { Example: a: [any "a" "b"] b: ["aa"] parse "ab" a-b a b parse "aab" a-b a b } not-rule: cfunc [ {Generate a not A parse rule} a [block!] /local finish ] [ [ [ a (finish: [to end skip]) | (finish: []) ] finish ] ] comment { Example: a: [any "a" "b"] parse "ab" not-rule a parse "b" not-rule a parse "" not-rule a } to-rule: cfunc [ {generate a to A parse rule} a [block!] /local nxt finish ] [ [ ( finish: [to end skip] nxt: [skip] ) any [a (nxt: [to end skip] finish: []) nxt | nxt] finish ] ] comment { Example: space-or-br: to-rule [" " | "<br>"] result: "" parse/all "aa" [space-or-br copy result to end] probe result parse/all "a a<br>" [space-or-br copy result to end] probe result parse/all "ab<br> " [space-or-br copy result to end] probe result }