explicitly at runtime with the compile functions
(@code{peg-sexp-compile} and @code{peg-string-compile}).
-They can then be used for either parsing (@code{peg-parse}) or searching
+They can then be used for either parsing (@code{match-pattern}) or searching
(@code{search-for-pattern}). For convenience, @code{search-for-pattern}
also takes pattern literals in case you want to inline a simple search
(people often use regular expressions this way).
The most straightforward way to define a PEG is by using one of the
define macros (both of these macroexpand into @code{define}
expressions). These macros bind parsing functions to variables. These
-parsing functions may be invoked by @code{peg-parse} or
+parsing functions may be invoked by @code{match-pattern} or
@code{search-for-pattern}, which return a PEG match record. Raw data can be
retrieved from this record with the PEG match deconstructor functions.
More complicated (and perhaps enlightening) examples can be found in the
@end lisp
Then:
@lisp
-(peg-parse as-or-bs "aabbcc") @result{}
+(match-pattern as-or-bs "aabbcc") @result{}
#<peg start: 0 end: 2 string: aabbcc tree: aa>
-(peg-parse as-or-bs-tag "aabbcc") @result{}
+(match-pattern as-or-bs-tag "aabbcc") @result{}
#<peg start: 0 end: 2 string: aabbcc tree: (as-or-bs-tag (as-tag aa))>
@end lisp
@end lisp
Then:
@lisp
-(peg-parse as-or-bs "aabbcc") @result{}
+(match-pattern as-or-bs "aabbcc") @result{}
#<peg start: 0 end: 2 string: aabbcc tree: aa>
-(peg-parse as-or-bs-tag "aabbcc") @result{}
+(match-pattern as-or-bs-tag "aabbcc") @result{}
#<peg start: 0 end: 2 string: aabbcc tree: (as-or-bs-tag (as-tag aa))>
@end lisp
You can use this nonterminal with all of the regular PEG functions:
@lisp
-(peg-parse as "aaaaa") @result{}
+(match-pattern as "aaaaa") @result{}
#<peg start: 0 end: 5 string: bbbbb tree: bbbbb>
@end lisp
For our purposes, ``parsing'' means parsing a string into a tree
starting from the first character, while ``matching'' means searching
through the string for a substring. In practice, the only difference
-between the two functions is that @code{peg-parse} gives up if it can't
+between the two functions is that @code{match-pattern} gives up if it can't
find a valid substring starting at index 0 and @code{search-for-pattern} keeps
looking. They are both equally capable of ``parsing'' and ``matching''
given those constraints.
-@deffn {Scheme Procedure} peg-parse nonterm string
+@deffn {Scheme Procedure} match-pattern nonterm string
Parses @var{string} using the PEG stored in @var{nonterm}. If no match
-was found, @code{peg-parse} returns false. If a match was found, a PEG
+was found, @code{match-pattern} returns false. If a match was found, a PEG
match record is returned.
The @code{capture-type} argument to @code{define-nonterm} allows you to
@lisp
(define-nonterm as all (+ "a"))
-(peg-parse as "aabbcc") @result{}
+(match-pattern as "aabbcc") @result{}
#<peg start: 0 end: 2 string: aabbcc tree: (as aa)>
(define-nonterm as body (+ "a"))
-(peg-parse as "aabbcc") @result{}
+(match-pattern as "aabbcc") @result{}
#<peg start: 0 end: 2 string: aabbcc tree: aa>
(define-nonterm as none (+ "a"))
-(peg-parse as "aabbcc") @result{}
+(match-pattern as "aabbcc") @result{}
#<peg start: 0 end: 2 string: aabbcc tree: ()>
(define-nonterm bs body (+ "b"))
-(peg-parse bs "aabbcc") @result{}
+(match-pattern bs "aabbcc") @result{}
#f
@end lisp
@end deffn
@end deffn
@subsubheading PEG Match Records
-The @code{peg-parse} and @code{search-for-pattern} functions both return PEG
+The @code{match-pattern} and @code{search-for-pattern} functions both return PEG
match records. Actual information can be extracted from these with the
following functions.
nonterminal yields the same results:
@lisp
-(peg:tree (peg-parse passwd *etc-passwd*)) @result{}
+(peg:tree (match-pattern passwd *etc-passwd*)) @result{}
((entry "root:x:0:0:root:/root:/bin/bash")
(entry "daemon:x:1:1:daemon:/usr/sbin:/bin/sh")
(entry "bin:x:2:2:bin:/bin:/bin/sh")
However, here is something to be wary of:
@lisp
-(peg:tree (peg-parse passwd "one entry")) @result{}
+(peg:tree (match-pattern passwd "one entry")) @result{}
(entry "one entry")
@end lisp
What we want here is @code{keyword-flatten}.
@lisp
-(keyword-flatten '(entry) (peg:tree (peg-parse passwd *etc-passwd*))) @result{}
+(keyword-flatten '(entry) (peg:tree (match-pattern passwd *etc-passwd*))) @result{}
((entry "root:x:0:0:root:/root:/bin/bash")
(entry "daemon:x:1:1:daemon:/usr/sbin:/bin/sh")
(entry "bin:x:2:2:bin:/bin:/bin/sh")
(entry "sys:x:3:3:sys:/dev:/bin/sh")
(entry "nobody:x:65534:65534:nobody:/nonexistent:/bin/sh")
(entry "messagebus:x:103:107::/var/run/dbus:/bin/false"))
-(keyword-flatten '(entry) (peg:tree (peg-parse passwd "one entry"))) @result{}
+(keyword-flatten '(entry) (peg:tree (match-pattern passwd "one entry"))) @result{}
((entry "one entry"))
@end lisp
@lisp
(define-nonterm tag-passwd all (peg "entry* !."))
-(peg:tree (peg-parse tag-passwd *etc-passwd*)) @result{}
+(peg:tree (match-pattern tag-passwd *etc-passwd*)) @result{}
(tag-passwd
(entry "root:x:0:0:root:/root:/bin/bash")
(entry "daemon:x:1:1:daemon:/usr/sbin:/bin/sh")
(entry "sys:x:3:3:sys:/dev:/bin/sh")
(entry "nobody:x:65534:65534:nobody:/nonexistent:/bin/sh")
(entry "messagebus:x:103:107::/var/run/dbus:/bin/false"))
-(peg:tree (peg-parse tag-passwd "one entry"))
+(peg:tree (match-pattern tag-passwd "one entry"))
(tag-passwd
(entry "one entry"))
@end lisp
Then:
@lisp
-(peg:tree (peg-parse expr "1+1/2*3+(1+1)/2")) @result{}
+(peg:tree (match-pattern expr "1+1/2*3+(1+1)/2")) @result{}
(sum (product (value (number "1")))
"+"
(sum (product
Then:
@lisp
-(apply parse-expr (peg:tree (peg-parse expr "1+1/2*3+(1+1)/2"))) @result{}
+(apply parse-expr (peg:tree (match-pattern expr "1+1/2*3+(1+1)/2"))) @result{}
(+ 1 (+ (/ 1 (* 2 3)) (/ (+ 1 1) 2)))
@end lisp
Then:
@lisp
-(apply parse-expr (peg:tree (peg-parse expr "1+1/2*3+(1+1)/2"))) @result{}
+(apply parse-expr (peg:tree (match-pattern expr "1+1/2*3+(1+1)/2"))) @result{}
(+ (+ 1 (* (/ 1 2) 3)) (/ (+ 1 1) 2))
@end lisp
Then:
@lisp
-(peg-parse cfunc "int square(int a) @{ return a*a;@}") @result{}
+(match-pattern cfunc "int square(int a) @{ return a*a;@}") @result{}
(32
(cfunc (ctype "int")
(cname "square")
And:
@lisp
-(peg-parse cfunc "int mod(int a, int b) @{ int c = a/b;return a-b*c; @}") @result{}
+(match-pattern cfunc "int mod(int a, int b) @{ int c = a/b;return a-b*c; @}") @result{}
(52
(cfunc (ctype "int")
(cname "mod")
By wrapping all the @code{carg} nonterminals in a @code{cargs}
nonterminal, we were able to remove any ambiguity in the parsing
structure and avoid having to call @code{context-flatten} on the output
-of @code{peg-parse}. We used the same trick with the @code{cstatement}
+of @code{match-pattern}. We used the same trick with the @code{cstatement}
nonterminals, wrapping them in a @code{cbody} nonterminal.
The whitespace nonterminal @code{cSP} used here is a (very) useful
doesn't have any more data.
The one caveat is that if the extra data it returns is a list, any
-adjacent strings in that list will be appended by @code{peg-parse}. For
+adjacent strings in that list will be appended by @code{match-pattern}. For
instance, if a parsing function returns @code{(13 ("a" "b" "c"))},
-@code{peg-parse} will take @code{(13 ("abc"))} as its value.
+@code{match-pattern} will take @code{(13 ("abc"))} as its value.
For example, here is a function to match ``ab'' using the actual
interface.
@end lisp
The above function can be used to match a string by running
-@code{(peg-parse match-a-b "ab")}.
+@code{(match-pattern match-a-b "ab")}.
@subsubheading Code Generators and Extensible Syntax
(pass-if
"equivalence of definitions"
(equal?
- (peg:tree (peg-parse (@@ (ice-9 peg) peg-grammar) (@@ (ice-9 peg) peg-as-peg)))
+ (peg:tree (match-pattern (@@ (ice-9 peg) peg-grammar) (@@ (ice-9 peg) peg-as-peg)))
(tree-map
grammar-transform
- (peg:tree (peg-parse grammar (@@ (ice-9 peg) peg-as-peg)))))))
+ (peg:tree (match-pattern grammar (@@ (ice-9 peg) peg-as-peg)))))))
;; A grammar for pascal-style comments from Wikipedia.
(define comment-grammar
;; Pascal-style comment parsing
"simple comment"
(equal?
- (peg-parse C "(*blah*)")
+ (match-pattern C "(*blah*)")
(make-prec 0 8 "(*blah*)"
'((Begin "(*") "blah" (End "*)")))))
(pass-if
"simple comment padded"
(equal?
- (peg-parse C "(*blah*)abc")
+ (match-pattern C "(*blah*)abc")
(make-prec 0 8 "(*blah*)abc"
'((Begin "(*") "blah" (End "*)")))))
(pass-if
"nested comment"
(equal?
- (peg-parse C "(*1(*2*)*)")
+ (match-pattern C "(*1(*2*)*)")
(make-prec 0 10 "(*1(*2*)*)"
'((Begin "(*") ("1" ((Begin "(*") "2" (End "*)"))) (End "*)")))))
(pass-if
"early termination"
- (not (peg-parse C "(*blah")))
+ (not (match-pattern C "(*blah")))
(pass-if
"never starts"
- (not (peg-parse C "blah")))
+ (not (match-pattern C "blah")))
;; /etc/passwd parsing
(pass-if
"/etc/passwd"
(equal?
- (peg-parse passwd *etc-passwd*)
+ (match-pattern passwd *etc-passwd*)
(make-prec 0 220 *etc-passwd*
'(passwd (entry (login "root") (pass "x") (uid "0") (gid "0") (nameORcomment "root") (homedir (path (pathELEMENT "root"))) (shell (path (pathELEMENT "bin") (pathELEMENT "bash")))) (entry (login "daemon") (pass "x") (uid "1") (gid "1") (nameORcomment "daemon") (homedir (path (pathELEMENT "usr") (pathELEMENT "sbin"))) (shell (path (pathELEMENT "bin") (pathELEMENT "sh")))) (entry (login "bin") (pass "x") (uid "2") (gid "2") (nameORcomment "bin") (homedir (path (pathELEMENT "bin"))) (shell (path (pathELEMENT "bin") (pathELEMENT "sh")))) (entry (login "sys") (pass "x") (uid "3") (gid "3") (nameORcomment "sys") (homedir (path (pathELEMENT "dev"))) (shell (path (pathELEMENT "bin") (pathELEMENT "sh")))) (entry (login "nobody") (pass "x") (uid "65534") (gid "65534") (nameORcomment "nobody") (homedir (path (pathELEMENT "nonexistent"))) (shell (path (pathELEMENT "bin") (pathELEMENT "sh")))) (entry (login "messagebus") (pass "x") (uid "103") (gid "107") nameORcomment (homedir (path (pathELEMENT "var") (pathELEMENT "run") (pathELEMENT "dbus"))) (shell (path (pathELEMENT "bin") (pathELEMENT "false")))))))))
(apply parse-sum (car rest))))
(define parse-expr parse-sum)
-(define (eq-parse str) (apply parse-expr (peg:tree (peg-parse expr str))))
+(define (eq-parse str) (apply parse-expr (peg:tree (match-pattern expr str))))
(with-test-prefix "Parsing right-associative equations"
(pass-if
(define parse-product (make-left-parser parse-value))
(define parse-sum (make-left-parser parse-product))
(define parse-expr parse-sum)
-(define (eq-parse str) (apply parse-expr (peg:tree (peg-parse expr str))))
+(define (eq-parse str) (apply parse-expr (peg:tree (match-pattern expr str))))
(with-test-prefix "Parsing left-associative equations"
(pass-if