]> gitweb.factorcode.org Git - factor.git/commitdiff
Moving parts of extra/peg to basis
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sat, 23 Aug 2008 04:04:24 +0000 (23:04 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sat, 23 Aug 2008 04:04:24 +0000 (23:04 -0500)
16 files changed:
basis/peg/authors.txt [new file with mode: 0644]
basis/peg/parsers/parsers-docs.factor [new file with mode: 0755]
basis/peg/parsers/parsers-tests.factor [new file with mode: 0644]
basis/peg/parsers/parsers.factor [new file with mode: 0755]
basis/peg/peg-docs.factor [new file with mode: 0644]
basis/peg/peg-tests.factor [new file with mode: 0644]
basis/peg/summary.txt [new file with mode: 0644]
basis/peg/tags.txt [new file with mode: 0644]
extra/peg/authors.txt [deleted file]
extra/peg/parsers/parsers-docs.factor [deleted file]
extra/peg/parsers/parsers-tests.factor [deleted file]
extra/peg/parsers/parsers.factor [deleted file]
extra/peg/peg-docs.factor [deleted file]
extra/peg/peg-tests.factor [deleted file]
extra/peg/summary.txt [deleted file]
extra/peg/tags.txt [deleted file]

diff --git a/basis/peg/authors.txt b/basis/peg/authors.txt
new file mode 100644 (file)
index 0000000..44b06f9
--- /dev/null
@@ -0,0 +1 @@
+Chris Double
diff --git a/basis/peg/parsers/parsers-docs.factor b/basis/peg/parsers/parsers-docs.factor
new file mode 100755 (executable)
index 0000000..7ffd458
--- /dev/null
@@ -0,0 +1,179 @@
+! Copyright (C) 2008 Chris Double, Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.markup help.syntax peg peg.parsers.private
+unicode.categories ;
+IN: peg.parsers
+
+HELP: 1token
+{ $values
+    { "ch" "a character" }
+    { "parser" "a parser" }
+} { $description
+    "Calls 1string on a character and returns a parser that matches that character."
+} { $examples
+    { $example "USING: peg peg.parsers prettyprint ;" "\"a\" CHAR: a 1token parse ." "\"a\"" }
+} { $see-also 'string' } ;
+
+HELP: (list-of)
+{ $values
+    { "items" "a sequence" }
+    { "separator" "a parser" }
+    { "repeat1?" "a boolean" }
+    { "parser" "a parser" }
+} { $description
+    "Returns a parser that returns a list of items separated by the separator parser.  Does not hide the separators."
+} { $see-also list-of list-of-many } ;
+
+HELP: list-of
+{ $values
+    { "items" "a sequence" }
+    { "separator" "a parser" }
+    { "parser" "a parser" }
+} { $description
+    "Returns a parser that returns a list of items separated by the separator parser.  Hides the separators and matches a list of one or more items."
+} { $notes "Use " { $link list-of-many } " to ensure a list contains two or more items." }
+{ $examples
+    { $example "USING: peg peg.parsers prettyprint ;" "\"a\" \"a\" token \",\" token list-of parse  ." "V{ \"a\" }" }
+    { $example "USING: peg peg.parsers prettyprint ;" "\"a,a,a,a\" \"a\" token \",\" token list-of parse ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
+} { $see-also list-of-many } ;
+    
+HELP: list-of-many
+{ $values
+    { "items" "a sequence" }
+    { "separator" "a parser" }
+    { "parser" "a parser" }
+} { $description
+    "Returns a parser that returns a list of items separated by the separator parser.  Hides the separators and matches a list of two or more items."
+} { $notes "Use " { $link list-of } " to return a list of only one item."
+} { $examples
+    { $code "USING: peg peg.parsers prettyprint ;" "\"a\" \"a\" token \",\" token list-of-many parse => exception" }
+    { $example "USING: peg peg.parsers prettyprint ;" "\"a,a,a,a\" \"a\" token \",\" token list-of-many parse ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
+} { $see-also list-of } ;
+
+HELP: epsilon
+{ $values
+    { "parser" "a parser" }
+} { $description
+    "Returns a parser that matches the empty sequence."
+} ;
+
+HELP: any-char
+{ $values
+    { "parser" "a parser" }
+} { $description
+    "Returns a parser that matches the any single character."
+} ;
+
+HELP: exactly-n
+{ $values
+    { "parser" "a parser" }
+    { "n" "an integer" }
+    { "parser'" "a parser" }
+} { $description
+    "Returns a parser that matches an exact repetition of the input parser."
+} { $examples
+    { $code "USING: peg peg.parsers prettyprint ;" "\"aaa\" \"a\" token 4 exactly-n parse => exception" }
+    { $example "USING: peg peg.parsers prettyprint ;" "\"aaaa\" \"a\" token 4 exactly-n parse ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
+} { $see-also at-least-n at-most-n from-m-to-n } ;
+
+HELP: at-least-n
+{ $values
+    { "parser" "a parser" }
+    { "n" "an integer" }
+    { "parser'" "a parser" }
+} { $description
+    "Returns a parser that matches n or more repetitions of the input parser."
+} { $examples
+    { $code "USING: peg peg.parsers prettyprint ;" "\"aaa\" \"a\" token 4 at-least-n parse => exception"}
+    { $example "USING: peg peg.parsers prettyprint ;" "\"aaaa\" \"a\" token 4 at-least-n parse ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
+    { $example "USING: peg peg.parsers prettyprint ;" "\"aaaaa\" \"a\" token 4 at-least-n parse ." "V{ \"a\" \"a\" \"a\" \"a\" \"a\" }" }
+} { $see-also exactly-n at-most-n from-m-to-n } ;
+
+HELP: at-most-n
+{ $values
+    { "parser" "a parser" }
+    { "n" "an integer" }
+    { "parser'" "a parser" }
+} { $description
+    "Returns a parser that matches n or fewer repetitions of the input parser."
+} { $examples
+    { $example "USING: peg peg.parsers prettyprint ;" "\"aaaa\" \"a\" token 4 at-most-n parse ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
+    { $example "USING: peg peg.parsers prettyprint ;" "\"aaaaa\" \"a\" token 4 at-most-n parse ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
+} { $see-also exactly-n at-least-n from-m-to-n } ;
+
+HELP: from-m-to-n
+{ $values
+    { "parser" "a parser" }
+    { "m" "an integer" }
+    { "n" "an integer" }
+    { "parser'" "a parser" }
+} { $description
+    "Returns a parser that matches between and including m to n repetitions of the input parser."
+} { $examples
+    { $example "USING: peg peg.parsers prettyprint ;" "\"aaa\" \"a\" token 3 4 from-m-to-n parse ." "V{ \"a\" \"a\" \"a\" }" }
+    { $example "USING: peg peg.parsers prettyprint ;" "\"aaaa\" \"a\" token 3 4 from-m-to-n parse ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
+    { $example "USING: peg peg.parsers prettyprint ;" "\"aaaaa\" \"a\" token 3 4 from-m-to-n parse ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
+} { $see-also exactly-n at-most-n at-least-n } ;
+
+HELP: pack
+{ $values
+    { "begin" "a parser" }
+    { "body" "a parser" }
+    { "end" "a parser" }
+    { "parser" "a parser" }
+} { $description
+    "Returns a parser that parses the begin, body, and end parsers in order.  The begin and end parsers are hidden."
+} { $examples
+    { $example "USING: peg peg.parsers prettyprint ;" "\"hi123bye\" \"hi\" token 'integer' \"bye\" token pack parse ." "123" }
+} { $see-also surrounded-by } ;
+
+HELP: surrounded-by
+{ $values
+    { "parser" "a parser" }
+    { "begin" "a string" }
+    { "end" "a string" }
+    { "parser'" "a parser" }
+} { $description
+    "Calls token on begin and end to make them into string parsers.  Returns a parser that parses the begin, body, and end parsers in order.  The begin and end parsers are hidden."
+} { $examples
+    { $example "USING: peg peg.parsers prettyprint ;" "\"hi123bye\" 'integer' \"hi\" \"bye\" surrounded-by parse ." "123" }
+} { $see-also pack } ;
+
+HELP: 'digit'
+{ $values
+    { "parser" "a parser" }
+} { $description
+    "Returns a parser that matches a single digit as defined by the " { $link digit? } " word."
+} { $see-also 'integer' } ;
+
+HELP: 'integer'
+{ $values
+    { "parser" "a parser" }
+} { $description
+    "Returns a parser that matches an integer composed of digits, as defined by the " { $link 'digit' } " word."
+} { $see-also 'digit' 'string' } ;
+
+HELP: 'string'
+{ $values
+    { "parser" "a parser" }
+} { $description
+    "Returns a parser that matches an string composed of a \", anything that is not \", and another \"."
+} { $see-also 'integer' } ;
+
+HELP: range-pattern
+{ $values
+    { "pattern" "a string" }
+    { "parser" "a parser" }
+} { $description
+"Returns a parser that matches a single character based on the set "
+"of characters in the pattern string."
+"Any single character in the pattern matches that character. "
+"If the pattern begins with a ^ then the set is negated "
+"(the element matches any character not in the set). Any pair "
+"of characters separated with a dash (-) represents the "
+"range of characters from the first to the second, inclusive."
+{ $examples
+    { $example "USING: peg peg.parsers prettyprint strings ;" "\"a\" \"_a-zA-Z\" range-pattern parse 1string ." "\"a\"" } 
+    { $code "USING: peg peg.parsers prettyprint ;\n\"0\" \"^0-9\" range-pattern parse => exception"} 
+}
+}  ;
diff --git a/basis/peg/parsers/parsers-tests.factor b/basis/peg/parsers/parsers-tests.factor
new file mode 100644 (file)
index 0000000..20d19c9
--- /dev/null
@@ -0,0 +1,51 @@
+USING: kernel peg peg.parsers tools.test accessors ;
+IN: peg.parsers.tests
+
+{ V{ "a" } }
+[ "a" "a" token "," token list-of parse ] unit-test
+
+{ V{ "a" "a" "a" "a" } }
+[ "a,a,a,a" "a" token "," token list-of parse ] unit-test
+
+[ "a" "a" token "," token list-of-many parse ] must-fail
+
+{ V{ "a" "a" "a" "a" } }
+[ "a,a,a,a" "a" token "," token list-of-many parse ] unit-test
+
+[ "aaa" "a" token 4 exactly-n parse ] must-fail
+
+{ V{ "a" "a" "a" "a" } }
+[ "aaaa" "a" token 4 exactly-n parse ] unit-test
+
+[ "aaa" "a" token 4 at-least-n parse ] must-fail
+
+{ V{ "a" "a" "a" "a" } }
+[ "aaaa" "a" token 4 at-least-n parse ] unit-test
+
+{ V{ "a" "a" "a" "a" "a" } }
+[ "aaaaa" "a" token 4 at-least-n parse ] unit-test
+
+{ V{ "a" "a" "a" "a" } }
+[ "aaaa" "a" token 4 at-most-n parse ] unit-test
+
+{ V{ "a" "a" "a" "a" } }
+[ "aaaaa" "a" token 4 at-most-n parse ] unit-test
+
+{ V{ "a" "a" "a" } }
+[ "aaa" "a" token 3 4 from-m-to-n parse ] unit-test
+
+{ V{ "a" "a" "a" "a" } }
+[ "aaaa" "a" token 3 4 from-m-to-n parse ] unit-test
+
+{ V{ "a" "a" "a" "a" } }
+[ "aaaaa" "a" token 3 4 from-m-to-n parse ] unit-test
+
+{ 97 }
+[ "a" any-char parse ] unit-test
+
+{ V{ } }
+[ "" epsilon parse ] unit-test
+
+{ "a" } [
+  "a" "a" token just parse
+] unit-test
\ No newline at end of file
diff --git a/basis/peg/parsers/parsers.factor b/basis/peg/parsers/parsers.factor
new file mode 100755 (executable)
index 0000000..b5b2886
--- /dev/null
@@ -0,0 +1,111 @@
+! Copyright (C) 2007, 2008 Chris Double, Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel sequences strings namespaces math assocs shuffle 
+     vectors arrays math.parser 
+     unicode.categories sequences.deep peg peg.private 
+     peg.search math.ranges words ;
+IN: peg.parsers
+
+TUPLE: just-parser p1 ;
+
+: just-pattern
+  [
+    execute dup [
+      dup parse-result-remaining empty? [ drop f ] unless
+    ] when
+  ] ;
+
+
+M: just-parser (compile) ( parser -- quot )
+  just-parser-p1 compile-parser just-pattern curry ;
+
+: just ( parser -- parser )
+  just-parser boa wrap-peg ;
+
+: 1token ( ch -- parser ) 1string token ;
+
+: (list-of) ( items separator repeat1? -- parser )
+  >r over 2seq r> [ repeat1 ] [ repeat0 ] if [ concat ] action 2seq
+  [ unclip 1vector swap first append ] action ;
+
+: list-of ( items separator -- parser )
+  hide f (list-of) ;
+
+: list-of-many ( items separator -- parser )
+  hide t (list-of) ;
+
+: epsilon ( -- parser ) V{ } token ;
+
+: any-char ( -- parser ) [ drop t ] satisfy ;
+
+<PRIVATE
+
+: flatten-vectors ( pair -- vector )
+  first2 over push-all ;
+
+PRIVATE>
+
+: exactly-n ( parser n -- parser' )
+  swap <repetition> seq ;
+
+: at-most-n ( parser n -- parser' )
+  dup zero? [
+    2drop epsilon
+  ] [
+    2dup exactly-n
+    -rot 1- at-most-n 2choice
+  ] if ;
+
+: at-least-n ( parser n -- parser' )
+  dupd exactly-n swap repeat0 2seq
+  [ flatten-vectors ] action ;
+
+: from-m-to-n ( parser m n -- parser' )
+  >r [ exactly-n ] 2keep r> swap - at-most-n 2seq
+  [ flatten-vectors ] action ;
+
+: pack ( begin body end -- parser )
+  >r >r hide r> r> hide 3seq [ first ] action ;
+
+: surrounded-by ( parser begin end -- parser' )
+  [ token ] bi@ swapd pack ;
+
+: 'digit' ( -- parser )
+  [ digit? ] satisfy [ digit> ] action ;
+
+: 'integer' ( -- parser )
+  'digit' repeat1 [ 10 digits>integer ] action ;
+
+: 'string' ( -- parser )
+  [
+    [ CHAR: " = ] satisfy hide ,
+    [ CHAR: " = not ] satisfy repeat0 ,
+    [ CHAR: " = ] satisfy hide ,
+  ] seq* [ first >string ] action ;
+
+: (range-pattern) ( pattern -- string )
+  #! Given a range pattern, produce a string containing
+  #! all characters within that range.
+  [ 
+    any-char , 
+    [ CHAR: - = ] satisfy hide , 
+    any-char , 
+  ] seq* [
+    first2 [a,b] >string    
+  ] action
+  replace ;
+
+: range-pattern ( pattern -- parser )
+  #! 'pattern' is a set of characters describing the
+  #! parser to be produced. Any single character in
+  #! the pattern matches that character. If the pattern
+  #! begins with a ^ then the set is negated (the element
+  #! matches any character not in the set). Any pair of
+  #! characters separated with a dash (-) represents the
+  #! range of characters from the first to the second,
+  #! inclusive.
+  dup first CHAR: ^ = [
+    rest (range-pattern) [ member? not ] curry satisfy 
+  ] [
+    (range-pattern) [ member? ] curry satisfy
+  ] if ;
diff --git a/basis/peg/peg-docs.factor b/basis/peg/peg-docs.factor
new file mode 100644 (file)
index 0000000..00390c1
--- /dev/null
@@ -0,0 +1,180 @@
+! Copyright (C) 2007 Chris Double.\r
+! See http://factorcode.org/license.txt for BSD license.\r
+USING: help.markup help.syntax ;\r
+IN: peg\r
+\r
+HELP: parse\r
+{ $values \r
+  { "input" "a string" } \r
+  { "parser" "a parser" } \r
+  { "ast" "an object" } \r
+}\r
+{ $description \r
+    "Given the input string, parse it using the given parser. The result is the abstract "\r
+    "syntax tree returned by the parser." } \r
+{ $see-also compile } ;\r
+\r
+HELP: compile\r
+{ $values \r
+  { "parser" "a parser" } \r
+  { "word" "a word" } \r
+}\r
+{ $description \r
+    "Compile the parser to a word. The word will have stack effect ( -- ast )."\r
+} \r
+{ $see-also parse } ;\r
+\r
+HELP: token\r
+{ $values \r
+  { "string" "a string" } \r
+  { "parser" "a parser" } \r
+}\r
+{ $description \r
+    "Returns a parser that matches the given string." } ;\r
+\r
+HELP: satisfy\r
+{ $values \r
+  { "quot" "a quotation" } \r
+  { "parser" "a parser" } \r
+}\r
+{ $description \r
+    "Returns a parser that calls the quotation on the first character of the input string, "\r
+    "succeeding if that quotation returns true. The AST is the character from the string." } ;\r
+\r
+HELP: range\r
+{ $values \r
+  { "min" "a character" } \r
+  { "max" "a character" } \r
+  { "parser" "a parser" } \r
+}\r
+{ $description \r
+    "Returns a parser that matches a single character that lies within the range of characters given, inclusive." }\r
+{ $examples { $code ": digit ( -- parser ) CHAR: 0 CHAR: 9 range ;" } } ;\r
+\r
+HELP: seq\r
+{ $values \r
+  { "seq" "a sequence of parsers" } \r
+  { "parser" "a parser" } \r
+}\r
+{ $description \r
+    "Returns a parser that calls all parsers in the given sequence, in order. The parser succeeds if "\r
+    "all the parsers succeed, otherwise it fails. The AST produced is a sequence of the AST produced by "\r
+    "the individual parsers." } ;\r
+\r
+HELP: choice\r
+{ $values \r
+  { "seq" "a sequence of parsers" } \r
+  { "parser" "a parser" } \r
+}\r
+{ $description \r
+    "Returns a parser that will try all the parsers in the sequence, in order, until one succeeds. "\r
+    "The resulting AST is that produced by the successful parser." } ;\r
+\r
+HELP: repeat0\r
+{ $values \r
+  { "parser" "a parser" } \r
+}\r
+{ $description \r
+    "Returns a parser that parses 0 or more instances of the 'p1' parser. The AST produced is "\r
+    "an array of the AST produced by the 'p1' parser. An empty array indicates 0 instances were "\r
+    "parsed." } ;\r
+\r
+HELP: repeat1\r
+{ $values \r
+  { "parser" "a parser" } \r
+}\r
+{ $description \r
+    "Returns a parser that parses 1 or more instances of the 'p1' parser. The AST produced is "\r
+    "an array of the AST produced by the 'p1' parser." } ;\r
+\r
+HELP: optional\r
+{ $values \r
+  { "parser" "a parser" } \r
+}\r
+{ $description \r
+    "Returns a parser that parses 0 or 1 instances of the 'p1' parser. The AST produced is "\r
+    "'f' if 0 instances are parsed the AST produced is 'f', otherwise it is the AST produced by 'p1'." } ;\r
+\r
+HELP: semantic\r
+{ $values \r
+  { "parser" "a parser" } \r
+  { "quot" "a quotation with stack effect ( object -- bool )" } \r
+}\r
+{ $description \r
+    "Returns a parser that succeeds if the 'p1' parser succeeds and the quotation called with "\r
+    "the AST produced by 'p1' on the stack returns true." }\r
+{ $examples \r
+  { $example "USING: kernel math peg prettyprint ;" "\"C\" [ drop t ] satisfy [ 66 > ] semantic parse ." "67" } \r
+} ;\r
+\r
+HELP: ensure\r
+{ $values \r
+  { "parser" "a parser" } \r
+}\r
+{ $description \r
+    "Returns a parser that succeeds if the 'p1' parser succeeds but does not add anything to the "\r
+    "AST and does not move the location in the input string. This can be used for lookahead and "\r
+    "disambiguation, along with the " { $link ensure-not } " word." }\r
+{ $examples { $code "\"0\" token ensure octal-parser" } } ;\r
+\r
+HELP: ensure-not\r
+{ $values \r
+  { "parser" "a parser" } \r
+}\r
+{ $description \r
+    "Returns a parser that succeeds if the 'p1' parser fails but does not add anything to the "\r
+    "AST and does not move the location in the input string. This can be used for lookahead and "\r
+    "disambiguation, along with the " { $link ensure } " word." }\r
+{ $code "\"+\" token \"=\" token ensure-not \"+=\" token 3array seq" } ;\r
+\r
+HELP: action\r
+{ $values \r
+  { "parser" "a parser" } \r
+  { "quot" "a quotation with stack effect ( ast -- ast )" } \r
+}\r
+{ $description \r
+    "Returns a parser that calls the 'p1' parser and applies the quotation to the AST resulting "\r
+    "from that parse. The result of the quotation is then used as the final AST. This can be used "\r
+    "for manipulating the parse tree to produce a AST better suited for the task at hand rather than "\r
+    "the default AST. If the quotation returns " { $link fail } " then the parser fails." }\r
+{ $code "CHAR: 0 CHAR: 9 range [ to-digit ] action" } ;\r
+\r
+HELP: sp\r
+{ $values \r
+  { "parser" "a parser" } \r
+}\r
+{ $description \r
+    "Returns a parser that calls the original parser 'p1' after stripping any whitespace "\r
+    " from the left of the input string." } ;\r
+\r
+HELP: hide\r
+{ $values \r
+  { "parser" "a parser" } \r
+}\r
+{ $description \r
+    "Returns a parser that succeeds if the original parser succeeds, but does not " \r
+    "put any result in the AST. Useful for ignoring 'syntax' in the AST." }\r
+{ $code "\"[\" token hide number \"]\" token hide 3array seq" } ;\r
+\r
+HELP: delay\r
+{ $values \r
+  { "quot" "a quotation" } \r
+  { "parser" "a parser" } \r
+}\r
+{ $description \r
+    "Delays the construction of a parser until it is actually required to parse. This " \r
+    "allows for calling a parser that results in a recursive call to itself. The quotation "\r
+    "should return the constructed parser and is called the first time the parser is run."\r
+    "The compiled result is memoized for future runs. See " { $link box } " for a word "\r
+    "that calls the quotation at compile time." } ;\r
+\r
+HELP: box\r
+{ $values \r
+  { "quot" "a quotation" } \r
+  { "parser" "a parser" } \r
+}\r
+{ $description \r
+    "Delays the construction of a parser until the parser is compiled. The quotation "\r
+    "should return the constructed parser and is called when the parser is compiled."\r
+    "The compiled result is memoized for future runs. See " { $link delay } " for a word "\r
+    "that calls the quotation at runtime." } ;\r
diff --git a/basis/peg/peg-tests.factor b/basis/peg/peg-tests.factor
new file mode 100644 (file)
index 0000000..b11b101
--- /dev/null
@@ -0,0 +1,196 @@
+! Copyright (C) 2007 Chris Double.
+! See http://factorcode.org/license.txt for BSD license.
+!
+USING: kernel tools.test strings namespaces arrays sequences 
+       peg peg.private accessors words math accessors ;
+IN: peg.tests
+
+[
+  "endbegin" "begin" token parse
+] must-fail
+
+{ "begin" "end" } [
+  "beginend" "begin" token (parse) 
+  { ast>> remaining>> } get-slots
+  >string
+] unit-test
+
+[
+  "" CHAR: a CHAR: z range parse
+] must-fail
+
+[
+  "1bcd" CHAR: a CHAR: z range parse
+] must-fail
+
+{ CHAR: a } [
+  "abcd" CHAR: a CHAR: z range parse
+] unit-test
+
+{ CHAR: z } [
+  "zbcd" CHAR: a CHAR: z range parse
+] unit-test
+
+[
+  "bad" "a" token "b" token 2array seq parse
+] must-fail
+
+{ V{ "g" "o" } } [
+  "good" "g" token "o" token 2array seq parse
+] unit-test
+
+{ "a" } [
+  "abcd" "a" token "b" token 2array choice parse
+] unit-test
+
+{ "b" } [
+  "bbcd" "a" token "b" token 2array choice parse
+] unit-test
+
+[
+  "cbcd" "a" token "b" token 2array choice parse 
+] must-fail
+
+[
+  "" "a" token "b" token 2array choice parse 
+] must-fail
+
+{ 0 } [
+  "" "a" token repeat0 parse length
+] unit-test
+
+{ 0 } [
+  "b" "a" token repeat0 parse length
+] unit-test
+
+{ V{ "a" "a" "a" } } [
+  "aaab" "a" token repeat0 parse 
+] unit-test
+
+[
+  "" "a" token repeat1 parse 
+] must-fail
+
+[
+  "b" "a" token repeat1 parse 
+] must-fail
+
+{ V{ "a" "a" "a" } } [
+  "aaab" "a" token repeat1 parse
+] unit-test
+
+{ V{ "a" "b" } } [ 
+  "ab" "a" token optional "b" token 2array seq parse 
+] unit-test
+
+{ V{ f "b" } } [ 
+  "b" "a" token optional "b" token 2array seq parse 
+] unit-test
+
+[ 
+  "cb" "a" token optional "b" token 2array seq parse  
+] must-fail
+
+{ V{ CHAR: a CHAR: b } } [
+  "ab" "a" token ensure CHAR: a CHAR: z range dup 3array seq parse
+] unit-test
+
+[
+  "bb" "a" token ensure CHAR: a CHAR: z range 2array seq parse 
+] must-fail
+
+{ t } [
+  "a+b" 
+  "a" token "+" token dup ensure-not 2array seq "++" token 2array choice "b" token 3array seq
+  parse [ t ] [ f ] if
+] unit-test
+
+{ t } [
+  "a++b" 
+  "a" token "+" token dup ensure-not 2array seq "++" token 2array choice "b" token 3array seq
+  parse [ t ] [ f ] if
+] unit-test
+
+{ t } [
+  "a+b" 
+  "a" token "+" token "++" token 2array choice "b" token 3array seq
+  parse [ t ] [ f ] if
+] unit-test
+
+[
+  "a++b" 
+  "a" token "+" token "++" token 2array choice "b" token 3array seq
+  parse [ t ] [ f ] if
+] must-fail
+
+{ 1 } [
+  "a" "a" token [ drop 1 ] action parse 
+] unit-test
+
+{ V{ 1 1 } } [
+  "aa" "a" token [ drop 1 ] action dup 2array seq parse 
+] unit-test
+
+[
+  "b" "a" token [ drop 1 ] action parse 
+] must-fail
+
+[ 
+  "b" [ CHAR: a = ] satisfy parse 
+] must-fail
+
+{ CHAR: a } [ 
+  "a" [ CHAR: a = ] satisfy parse
+] unit-test
+
+{ "a" } [
+  "    a" "a" token sp parse
+] unit-test
+
+{ "a" } [
+  "a" "a" token sp parse
+] unit-test
+
+{ V{ "a" } } [
+  "[a]" "[" token hide "a" token "]" token hide 3array seq parse
+] unit-test
+
+[
+  "a]" "[" token hide "a" token "]" token hide 3array seq parse 
+] must-fail
+
+
+{ V{ "1" "-" "1" } V{ "1" "+" "1" } } [
+  [
+    [ "1" token , "-" token , "1" token , ] seq* ,
+    [ "1" token , "+" token , "1" token , ] seq* ,
+  ] choice* 
+  "1-1" over parse swap
+  "1+1" swap parse
+] unit-test
+
+: expr ( -- parser ) 
+  #! Test direct left recursion. Currently left recursion should cause a
+  #! failure of that parser.
+  [ expr ] delay "+" token "1" token 3seq "1" token 2choice ;
+
+{ V{ V{ "1" "+" "1" } "+" "1" } } [
+  "1+1+1" expr parse   
+] unit-test
+
+{ t } [
+  #! Ensure a circular parser doesn't loop infinitely
+  [ f , "a" token , ] seq*
+  dup peg>> parsers>>
+  dupd 0 swap set-nth compile word?
+] unit-test
+
+[
+  "A" [ drop t ] satisfy [ 66 >= ] semantic parse 
+] must-fail
+
+{ CHAR: B } [
+  "B" [ drop t ] satisfy [ 66 >= ] semantic parse
+] unit-test
+
+{ f } [ \ + T{ parser f f f } equal? ] unit-test
\ No newline at end of file
diff --git a/basis/peg/summary.txt b/basis/peg/summary.txt
new file mode 100644 (file)
index 0000000..324a544
--- /dev/null
@@ -0,0 +1 @@
+Parsing Expression Grammar and Packrat Parser
diff --git a/basis/peg/tags.txt b/basis/peg/tags.txt
new file mode 100644 (file)
index 0000000..5af5dba
--- /dev/null
@@ -0,0 +1,2 @@
+text
+parsing
diff --git a/extra/peg/authors.txt b/extra/peg/authors.txt
deleted file mode 100644 (file)
index 44b06f9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Chris Double
diff --git a/extra/peg/parsers/parsers-docs.factor b/extra/peg/parsers/parsers-docs.factor
deleted file mode 100755 (executable)
index 7ffd458..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-! Copyright (C) 2008 Chris Double, Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: help.markup help.syntax peg peg.parsers.private
-unicode.categories ;
-IN: peg.parsers
-
-HELP: 1token
-{ $values
-    { "ch" "a character" }
-    { "parser" "a parser" }
-} { $description
-    "Calls 1string on a character and returns a parser that matches that character."
-} { $examples
-    { $example "USING: peg peg.parsers prettyprint ;" "\"a\" CHAR: a 1token parse ." "\"a\"" }
-} { $see-also 'string' } ;
-
-HELP: (list-of)
-{ $values
-    { "items" "a sequence" }
-    { "separator" "a parser" }
-    { "repeat1?" "a boolean" }
-    { "parser" "a parser" }
-} { $description
-    "Returns a parser that returns a list of items separated by the separator parser.  Does not hide the separators."
-} { $see-also list-of list-of-many } ;
-
-HELP: list-of
-{ $values
-    { "items" "a sequence" }
-    { "separator" "a parser" }
-    { "parser" "a parser" }
-} { $description
-    "Returns a parser that returns a list of items separated by the separator parser.  Hides the separators and matches a list of one or more items."
-} { $notes "Use " { $link list-of-many } " to ensure a list contains two or more items." }
-{ $examples
-    { $example "USING: peg peg.parsers prettyprint ;" "\"a\" \"a\" token \",\" token list-of parse  ." "V{ \"a\" }" }
-    { $example "USING: peg peg.parsers prettyprint ;" "\"a,a,a,a\" \"a\" token \",\" token list-of parse ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
-} { $see-also list-of-many } ;
-    
-HELP: list-of-many
-{ $values
-    { "items" "a sequence" }
-    { "separator" "a parser" }
-    { "parser" "a parser" }
-} { $description
-    "Returns a parser that returns a list of items separated by the separator parser.  Hides the separators and matches a list of two or more items."
-} { $notes "Use " { $link list-of } " to return a list of only one item."
-} { $examples
-    { $code "USING: peg peg.parsers prettyprint ;" "\"a\" \"a\" token \",\" token list-of-many parse => exception" }
-    { $example "USING: peg peg.parsers prettyprint ;" "\"a,a,a,a\" \"a\" token \",\" token list-of-many parse ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
-} { $see-also list-of } ;
-
-HELP: epsilon
-{ $values
-    { "parser" "a parser" }
-} { $description
-    "Returns a parser that matches the empty sequence."
-} ;
-
-HELP: any-char
-{ $values
-    { "parser" "a parser" }
-} { $description
-    "Returns a parser that matches the any single character."
-} ;
-
-HELP: exactly-n
-{ $values
-    { "parser" "a parser" }
-    { "n" "an integer" }
-    { "parser'" "a parser" }
-} { $description
-    "Returns a parser that matches an exact repetition of the input parser."
-} { $examples
-    { $code "USING: peg peg.parsers prettyprint ;" "\"aaa\" \"a\" token 4 exactly-n parse => exception" }
-    { $example "USING: peg peg.parsers prettyprint ;" "\"aaaa\" \"a\" token 4 exactly-n parse ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
-} { $see-also at-least-n at-most-n from-m-to-n } ;
-
-HELP: at-least-n
-{ $values
-    { "parser" "a parser" }
-    { "n" "an integer" }
-    { "parser'" "a parser" }
-} { $description
-    "Returns a parser that matches n or more repetitions of the input parser."
-} { $examples
-    { $code "USING: peg peg.parsers prettyprint ;" "\"aaa\" \"a\" token 4 at-least-n parse => exception"}
-    { $example "USING: peg peg.parsers prettyprint ;" "\"aaaa\" \"a\" token 4 at-least-n parse ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
-    { $example "USING: peg peg.parsers prettyprint ;" "\"aaaaa\" \"a\" token 4 at-least-n parse ." "V{ \"a\" \"a\" \"a\" \"a\" \"a\" }" }
-} { $see-also exactly-n at-most-n from-m-to-n } ;
-
-HELP: at-most-n
-{ $values
-    { "parser" "a parser" }
-    { "n" "an integer" }
-    { "parser'" "a parser" }
-} { $description
-    "Returns a parser that matches n or fewer repetitions of the input parser."
-} { $examples
-    { $example "USING: peg peg.parsers prettyprint ;" "\"aaaa\" \"a\" token 4 at-most-n parse ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
-    { $example "USING: peg peg.parsers prettyprint ;" "\"aaaaa\" \"a\" token 4 at-most-n parse ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
-} { $see-also exactly-n at-least-n from-m-to-n } ;
-
-HELP: from-m-to-n
-{ $values
-    { "parser" "a parser" }
-    { "m" "an integer" }
-    { "n" "an integer" }
-    { "parser'" "a parser" }
-} { $description
-    "Returns a parser that matches between and including m to n repetitions of the input parser."
-} { $examples
-    { $example "USING: peg peg.parsers prettyprint ;" "\"aaa\" \"a\" token 3 4 from-m-to-n parse ." "V{ \"a\" \"a\" \"a\" }" }
-    { $example "USING: peg peg.parsers prettyprint ;" "\"aaaa\" \"a\" token 3 4 from-m-to-n parse ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
-    { $example "USING: peg peg.parsers prettyprint ;" "\"aaaaa\" \"a\" token 3 4 from-m-to-n parse ." "V{ \"a\" \"a\" \"a\" \"a\" }" }
-} { $see-also exactly-n at-most-n at-least-n } ;
-
-HELP: pack
-{ $values
-    { "begin" "a parser" }
-    { "body" "a parser" }
-    { "end" "a parser" }
-    { "parser" "a parser" }
-} { $description
-    "Returns a parser that parses the begin, body, and end parsers in order.  The begin and end parsers are hidden."
-} { $examples
-    { $example "USING: peg peg.parsers prettyprint ;" "\"hi123bye\" \"hi\" token 'integer' \"bye\" token pack parse ." "123" }
-} { $see-also surrounded-by } ;
-
-HELP: surrounded-by
-{ $values
-    { "parser" "a parser" }
-    { "begin" "a string" }
-    { "end" "a string" }
-    { "parser'" "a parser" }
-} { $description
-    "Calls token on begin and end to make them into string parsers.  Returns a parser that parses the begin, body, and end parsers in order.  The begin and end parsers are hidden."
-} { $examples
-    { $example "USING: peg peg.parsers prettyprint ;" "\"hi123bye\" 'integer' \"hi\" \"bye\" surrounded-by parse ." "123" }
-} { $see-also pack } ;
-
-HELP: 'digit'
-{ $values
-    { "parser" "a parser" }
-} { $description
-    "Returns a parser that matches a single digit as defined by the " { $link digit? } " word."
-} { $see-also 'integer' } ;
-
-HELP: 'integer'
-{ $values
-    { "parser" "a parser" }
-} { $description
-    "Returns a parser that matches an integer composed of digits, as defined by the " { $link 'digit' } " word."
-} { $see-also 'digit' 'string' } ;
-
-HELP: 'string'
-{ $values
-    { "parser" "a parser" }
-} { $description
-    "Returns a parser that matches an string composed of a \", anything that is not \", and another \"."
-} { $see-also 'integer' } ;
-
-HELP: range-pattern
-{ $values
-    { "pattern" "a string" }
-    { "parser" "a parser" }
-} { $description
-"Returns a parser that matches a single character based on the set "
-"of characters in the pattern string."
-"Any single character in the pattern matches that character. "
-"If the pattern begins with a ^ then the set is negated "
-"(the element matches any character not in the set). Any pair "
-"of characters separated with a dash (-) represents the "
-"range of characters from the first to the second, inclusive."
-{ $examples
-    { $example "USING: peg peg.parsers prettyprint strings ;" "\"a\" \"_a-zA-Z\" range-pattern parse 1string ." "\"a\"" } 
-    { $code "USING: peg peg.parsers prettyprint ;\n\"0\" \"^0-9\" range-pattern parse => exception"} 
-}
-}  ;
diff --git a/extra/peg/parsers/parsers-tests.factor b/extra/peg/parsers/parsers-tests.factor
deleted file mode 100644 (file)
index 20d19c9..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-USING: kernel peg peg.parsers tools.test accessors ;
-IN: peg.parsers.tests
-
-{ V{ "a" } }
-[ "a" "a" token "," token list-of parse ] unit-test
-
-{ V{ "a" "a" "a" "a" } }
-[ "a,a,a,a" "a" token "," token list-of parse ] unit-test
-
-[ "a" "a" token "," token list-of-many parse ] must-fail
-
-{ V{ "a" "a" "a" "a" } }
-[ "a,a,a,a" "a" token "," token list-of-many parse ] unit-test
-
-[ "aaa" "a" token 4 exactly-n parse ] must-fail
-
-{ V{ "a" "a" "a" "a" } }
-[ "aaaa" "a" token 4 exactly-n parse ] unit-test
-
-[ "aaa" "a" token 4 at-least-n parse ] must-fail
-
-{ V{ "a" "a" "a" "a" } }
-[ "aaaa" "a" token 4 at-least-n parse ] unit-test
-
-{ V{ "a" "a" "a" "a" "a" } }
-[ "aaaaa" "a" token 4 at-least-n parse ] unit-test
-
-{ V{ "a" "a" "a" "a" } }
-[ "aaaa" "a" token 4 at-most-n parse ] unit-test
-
-{ V{ "a" "a" "a" "a" } }
-[ "aaaaa" "a" token 4 at-most-n parse ] unit-test
-
-{ V{ "a" "a" "a" } }
-[ "aaa" "a" token 3 4 from-m-to-n parse ] unit-test
-
-{ V{ "a" "a" "a" "a" } }
-[ "aaaa" "a" token 3 4 from-m-to-n parse ] unit-test
-
-{ V{ "a" "a" "a" "a" } }
-[ "aaaaa" "a" token 3 4 from-m-to-n parse ] unit-test
-
-{ 97 }
-[ "a" any-char parse ] unit-test
-
-{ V{ } }
-[ "" epsilon parse ] unit-test
-
-{ "a" } [
-  "a" "a" token just parse
-] unit-test
\ No newline at end of file
diff --git a/extra/peg/parsers/parsers.factor b/extra/peg/parsers/parsers.factor
deleted file mode 100755 (executable)
index b5b2886..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-! Copyright (C) 2007, 2008 Chris Double, Doug Coleman.
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel sequences strings namespaces math assocs shuffle 
-     vectors arrays math.parser 
-     unicode.categories sequences.deep peg peg.private 
-     peg.search math.ranges words ;
-IN: peg.parsers
-
-TUPLE: just-parser p1 ;
-
-: just-pattern
-  [
-    execute dup [
-      dup parse-result-remaining empty? [ drop f ] unless
-    ] when
-  ] ;
-
-
-M: just-parser (compile) ( parser -- quot )
-  just-parser-p1 compile-parser just-pattern curry ;
-
-: just ( parser -- parser )
-  just-parser boa wrap-peg ;
-
-: 1token ( ch -- parser ) 1string token ;
-
-: (list-of) ( items separator repeat1? -- parser )
-  >r over 2seq r> [ repeat1 ] [ repeat0 ] if [ concat ] action 2seq
-  [ unclip 1vector swap first append ] action ;
-
-: list-of ( items separator -- parser )
-  hide f (list-of) ;
-
-: list-of-many ( items separator -- parser )
-  hide t (list-of) ;
-
-: epsilon ( -- parser ) V{ } token ;
-
-: any-char ( -- parser ) [ drop t ] satisfy ;
-
-<PRIVATE
-
-: flatten-vectors ( pair -- vector )
-  first2 over push-all ;
-
-PRIVATE>
-
-: exactly-n ( parser n -- parser' )
-  swap <repetition> seq ;
-
-: at-most-n ( parser n -- parser' )
-  dup zero? [
-    2drop epsilon
-  ] [
-    2dup exactly-n
-    -rot 1- at-most-n 2choice
-  ] if ;
-
-: at-least-n ( parser n -- parser' )
-  dupd exactly-n swap repeat0 2seq
-  [ flatten-vectors ] action ;
-
-: from-m-to-n ( parser m n -- parser' )
-  >r [ exactly-n ] 2keep r> swap - at-most-n 2seq
-  [ flatten-vectors ] action ;
-
-: pack ( begin body end -- parser )
-  >r >r hide r> r> hide 3seq [ first ] action ;
-
-: surrounded-by ( parser begin end -- parser' )
-  [ token ] bi@ swapd pack ;
-
-: 'digit' ( -- parser )
-  [ digit? ] satisfy [ digit> ] action ;
-
-: 'integer' ( -- parser )
-  'digit' repeat1 [ 10 digits>integer ] action ;
-
-: 'string' ( -- parser )
-  [
-    [ CHAR: " = ] satisfy hide ,
-    [ CHAR: " = not ] satisfy repeat0 ,
-    [ CHAR: " = ] satisfy hide ,
-  ] seq* [ first >string ] action ;
-
-: (range-pattern) ( pattern -- string )
-  #! Given a range pattern, produce a string containing
-  #! all characters within that range.
-  [ 
-    any-char , 
-    [ CHAR: - = ] satisfy hide , 
-    any-char , 
-  ] seq* [
-    first2 [a,b] >string    
-  ] action
-  replace ;
-
-: range-pattern ( pattern -- parser )
-  #! 'pattern' is a set of characters describing the
-  #! parser to be produced. Any single character in
-  #! the pattern matches that character. If the pattern
-  #! begins with a ^ then the set is negated (the element
-  #! matches any character not in the set). Any pair of
-  #! characters separated with a dash (-) represents the
-  #! range of characters from the first to the second,
-  #! inclusive.
-  dup first CHAR: ^ = [
-    rest (range-pattern) [ member? not ] curry satisfy 
-  ] [
-    (range-pattern) [ member? ] curry satisfy
-  ] if ;
diff --git a/extra/peg/peg-docs.factor b/extra/peg/peg-docs.factor
deleted file mode 100644 (file)
index 00390c1..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-! Copyright (C) 2007 Chris Double.\r
-! See http://factorcode.org/license.txt for BSD license.\r
-USING: help.markup help.syntax ;\r
-IN: peg\r
-\r
-HELP: parse\r
-{ $values \r
-  { "input" "a string" } \r
-  { "parser" "a parser" } \r
-  { "ast" "an object" } \r
-}\r
-{ $description \r
-    "Given the input string, parse it using the given parser. The result is the abstract "\r
-    "syntax tree returned by the parser." } \r
-{ $see-also compile } ;\r
-\r
-HELP: compile\r
-{ $values \r
-  { "parser" "a parser" } \r
-  { "word" "a word" } \r
-}\r
-{ $description \r
-    "Compile the parser to a word. The word will have stack effect ( -- ast )."\r
-} \r
-{ $see-also parse } ;\r
-\r
-HELP: token\r
-{ $values \r
-  { "string" "a string" } \r
-  { "parser" "a parser" } \r
-}\r
-{ $description \r
-    "Returns a parser that matches the given string." } ;\r
-\r
-HELP: satisfy\r
-{ $values \r
-  { "quot" "a quotation" } \r
-  { "parser" "a parser" } \r
-}\r
-{ $description \r
-    "Returns a parser that calls the quotation on the first character of the input string, "\r
-    "succeeding if that quotation returns true. The AST is the character from the string." } ;\r
-\r
-HELP: range\r
-{ $values \r
-  { "min" "a character" } \r
-  { "max" "a character" } \r
-  { "parser" "a parser" } \r
-}\r
-{ $description \r
-    "Returns a parser that matches a single character that lies within the range of characters given, inclusive." }\r
-{ $examples { $code ": digit ( -- parser ) CHAR: 0 CHAR: 9 range ;" } } ;\r
-\r
-HELP: seq\r
-{ $values \r
-  { "seq" "a sequence of parsers" } \r
-  { "parser" "a parser" } \r
-}\r
-{ $description \r
-    "Returns a parser that calls all parsers in the given sequence, in order. The parser succeeds if "\r
-    "all the parsers succeed, otherwise it fails. The AST produced is a sequence of the AST produced by "\r
-    "the individual parsers." } ;\r
-\r
-HELP: choice\r
-{ $values \r
-  { "seq" "a sequence of parsers" } \r
-  { "parser" "a parser" } \r
-}\r
-{ $description \r
-    "Returns a parser that will try all the parsers in the sequence, in order, until one succeeds. "\r
-    "The resulting AST is that produced by the successful parser." } ;\r
-\r
-HELP: repeat0\r
-{ $values \r
-  { "parser" "a parser" } \r
-}\r
-{ $description \r
-    "Returns a parser that parses 0 or more instances of the 'p1' parser. The AST produced is "\r
-    "an array of the AST produced by the 'p1' parser. An empty array indicates 0 instances were "\r
-    "parsed." } ;\r
-\r
-HELP: repeat1\r
-{ $values \r
-  { "parser" "a parser" } \r
-}\r
-{ $description \r
-    "Returns a parser that parses 1 or more instances of the 'p1' parser. The AST produced is "\r
-    "an array of the AST produced by the 'p1' parser." } ;\r
-\r
-HELP: optional\r
-{ $values \r
-  { "parser" "a parser" } \r
-}\r
-{ $description \r
-    "Returns a parser that parses 0 or 1 instances of the 'p1' parser. The AST produced is "\r
-    "'f' if 0 instances are parsed the AST produced is 'f', otherwise it is the AST produced by 'p1'." } ;\r
-\r
-HELP: semantic\r
-{ $values \r
-  { "parser" "a parser" } \r
-  { "quot" "a quotation with stack effect ( object -- bool )" } \r
-}\r
-{ $description \r
-    "Returns a parser that succeeds if the 'p1' parser succeeds and the quotation called with "\r
-    "the AST produced by 'p1' on the stack returns true." }\r
-{ $examples \r
-  { $example "USING: kernel math peg prettyprint ;" "\"C\" [ drop t ] satisfy [ 66 > ] semantic parse ." "67" } \r
-} ;\r
-\r
-HELP: ensure\r
-{ $values \r
-  { "parser" "a parser" } \r
-}\r
-{ $description \r
-    "Returns a parser that succeeds if the 'p1' parser succeeds but does not add anything to the "\r
-    "AST and does not move the location in the input string. This can be used for lookahead and "\r
-    "disambiguation, along with the " { $link ensure-not } " word." }\r
-{ $examples { $code "\"0\" token ensure octal-parser" } } ;\r
-\r
-HELP: ensure-not\r
-{ $values \r
-  { "parser" "a parser" } \r
-}\r
-{ $description \r
-    "Returns a parser that succeeds if the 'p1' parser fails but does not add anything to the "\r
-    "AST and does not move the location in the input string. This can be used for lookahead and "\r
-    "disambiguation, along with the " { $link ensure } " word." }\r
-{ $code "\"+\" token \"=\" token ensure-not \"+=\" token 3array seq" } ;\r
-\r
-HELP: action\r
-{ $values \r
-  { "parser" "a parser" } \r
-  { "quot" "a quotation with stack effect ( ast -- ast )" } \r
-}\r
-{ $description \r
-    "Returns a parser that calls the 'p1' parser and applies the quotation to the AST resulting "\r
-    "from that parse. The result of the quotation is then used as the final AST. This can be used "\r
-    "for manipulating the parse tree to produce a AST better suited for the task at hand rather than "\r
-    "the default AST. If the quotation returns " { $link fail } " then the parser fails." }\r
-{ $code "CHAR: 0 CHAR: 9 range [ to-digit ] action" } ;\r
-\r
-HELP: sp\r
-{ $values \r
-  { "parser" "a parser" } \r
-}\r
-{ $description \r
-    "Returns a parser that calls the original parser 'p1' after stripping any whitespace "\r
-    " from the left of the input string." } ;\r
-\r
-HELP: hide\r
-{ $values \r
-  { "parser" "a parser" } \r
-}\r
-{ $description \r
-    "Returns a parser that succeeds if the original parser succeeds, but does not " \r
-    "put any result in the AST. Useful for ignoring 'syntax' in the AST." }\r
-{ $code "\"[\" token hide number \"]\" token hide 3array seq" } ;\r
-\r
-HELP: delay\r
-{ $values \r
-  { "quot" "a quotation" } \r
-  { "parser" "a parser" } \r
-}\r
-{ $description \r
-    "Delays the construction of a parser until it is actually required to parse. This " \r
-    "allows for calling a parser that results in a recursive call to itself. The quotation "\r
-    "should return the constructed parser and is called the first time the parser is run."\r
-    "The compiled result is memoized for future runs. See " { $link box } " for a word "\r
-    "that calls the quotation at compile time." } ;\r
-\r
-HELP: box\r
-{ $values \r
-  { "quot" "a quotation" } \r
-  { "parser" "a parser" } \r
-}\r
-{ $description \r
-    "Delays the construction of a parser until the parser is compiled. The quotation "\r
-    "should return the constructed parser and is called when the parser is compiled."\r
-    "The compiled result is memoized for future runs. See " { $link delay } " for a word "\r
-    "that calls the quotation at runtime." } ;\r
diff --git a/extra/peg/peg-tests.factor b/extra/peg/peg-tests.factor
deleted file mode 100644 (file)
index b11b101..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-! Copyright (C) 2007 Chris Double.
-! See http://factorcode.org/license.txt for BSD license.
-!
-USING: kernel tools.test strings namespaces arrays sequences 
-       peg peg.private accessors words math accessors ;
-IN: peg.tests
-
-[
-  "endbegin" "begin" token parse
-] must-fail
-
-{ "begin" "end" } [
-  "beginend" "begin" token (parse) 
-  { ast>> remaining>> } get-slots
-  >string
-] unit-test
-
-[
-  "" CHAR: a CHAR: z range parse
-] must-fail
-
-[
-  "1bcd" CHAR: a CHAR: z range parse
-] must-fail
-
-{ CHAR: a } [
-  "abcd" CHAR: a CHAR: z range parse
-] unit-test
-
-{ CHAR: z } [
-  "zbcd" CHAR: a CHAR: z range parse
-] unit-test
-
-[
-  "bad" "a" token "b" token 2array seq parse
-] must-fail
-
-{ V{ "g" "o" } } [
-  "good" "g" token "o" token 2array seq parse
-] unit-test
-
-{ "a" } [
-  "abcd" "a" token "b" token 2array choice parse
-] unit-test
-
-{ "b" } [
-  "bbcd" "a" token "b" token 2array choice parse
-] unit-test
-
-[
-  "cbcd" "a" token "b" token 2array choice parse 
-] must-fail
-
-[
-  "" "a" token "b" token 2array choice parse 
-] must-fail
-
-{ 0 } [
-  "" "a" token repeat0 parse length
-] unit-test
-
-{ 0 } [
-  "b" "a" token repeat0 parse length
-] unit-test
-
-{ V{ "a" "a" "a" } } [
-  "aaab" "a" token repeat0 parse 
-] unit-test
-
-[
-  "" "a" token repeat1 parse 
-] must-fail
-
-[
-  "b" "a" token repeat1 parse 
-] must-fail
-
-{ V{ "a" "a" "a" } } [
-  "aaab" "a" token repeat1 parse
-] unit-test
-
-{ V{ "a" "b" } } [ 
-  "ab" "a" token optional "b" token 2array seq parse 
-] unit-test
-
-{ V{ f "b" } } [ 
-  "b" "a" token optional "b" token 2array seq parse 
-] unit-test
-
-[ 
-  "cb" "a" token optional "b" token 2array seq parse  
-] must-fail
-
-{ V{ CHAR: a CHAR: b } } [
-  "ab" "a" token ensure CHAR: a CHAR: z range dup 3array seq parse
-] unit-test
-
-[
-  "bb" "a" token ensure CHAR: a CHAR: z range 2array seq parse 
-] must-fail
-
-{ t } [
-  "a+b" 
-  "a" token "+" token dup ensure-not 2array seq "++" token 2array choice "b" token 3array seq
-  parse [ t ] [ f ] if
-] unit-test
-
-{ t } [
-  "a++b" 
-  "a" token "+" token dup ensure-not 2array seq "++" token 2array choice "b" token 3array seq
-  parse [ t ] [ f ] if
-] unit-test
-
-{ t } [
-  "a+b" 
-  "a" token "+" token "++" token 2array choice "b" token 3array seq
-  parse [ t ] [ f ] if
-] unit-test
-
-[
-  "a++b" 
-  "a" token "+" token "++" token 2array choice "b" token 3array seq
-  parse [ t ] [ f ] if
-] must-fail
-
-{ 1 } [
-  "a" "a" token [ drop 1 ] action parse 
-] unit-test
-
-{ V{ 1 1 } } [
-  "aa" "a" token [ drop 1 ] action dup 2array seq parse 
-] unit-test
-
-[
-  "b" "a" token [ drop 1 ] action parse 
-] must-fail
-
-[ 
-  "b" [ CHAR: a = ] satisfy parse 
-] must-fail
-
-{ CHAR: a } [ 
-  "a" [ CHAR: a = ] satisfy parse
-] unit-test
-
-{ "a" } [
-  "    a" "a" token sp parse
-] unit-test
-
-{ "a" } [
-  "a" "a" token sp parse
-] unit-test
-
-{ V{ "a" } } [
-  "[a]" "[" token hide "a" token "]" token hide 3array seq parse
-] unit-test
-
-[
-  "a]" "[" token hide "a" token "]" token hide 3array seq parse 
-] must-fail
-
-
-{ V{ "1" "-" "1" } V{ "1" "+" "1" } } [
-  [
-    [ "1" token , "-" token , "1" token , ] seq* ,
-    [ "1" token , "+" token , "1" token , ] seq* ,
-  ] choice* 
-  "1-1" over parse swap
-  "1+1" swap parse
-] unit-test
-
-: expr ( -- parser ) 
-  #! Test direct left recursion. Currently left recursion should cause a
-  #! failure of that parser.
-  [ expr ] delay "+" token "1" token 3seq "1" token 2choice ;
-
-{ V{ V{ "1" "+" "1" } "+" "1" } } [
-  "1+1+1" expr parse   
-] unit-test
-
-{ t } [
-  #! Ensure a circular parser doesn't loop infinitely
-  [ f , "a" token , ] seq*
-  dup peg>> parsers>>
-  dupd 0 swap set-nth compile word?
-] unit-test
-
-[
-  "A" [ drop t ] satisfy [ 66 >= ] semantic parse 
-] must-fail
-
-{ CHAR: B } [
-  "B" [ drop t ] satisfy [ 66 >= ] semantic parse
-] unit-test
-
-{ f } [ \ + T{ parser f f f } equal? ] unit-test
\ No newline at end of file
diff --git a/extra/peg/summary.txt b/extra/peg/summary.txt
deleted file mode 100644 (file)
index 324a544..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Parsing Expression Grammar and Packrat Parser
diff --git a/extra/peg/tags.txt b/extra/peg/tags.txt
deleted file mode 100644 (file)
index 5af5dba..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-text
-parsing