! Copyright (C) 2007, 2008 Chris Double, Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. USING: accessors kernel make math math.parser math.ranges peg peg.private peg.search sequences strings unicode vectors ; IN: peg.parsers TUPLE: just-parser p1 ; CONSTANT: just-pattern [ dup [ dup remaining>> empty? [ drop f ] unless ] when ] M: just-parser (compile) ( parser -- quot ) p1>> compile-parser-quot just-pattern compose ; : just ( parser -- parser ) just-parser boa wrap-peg ; : 1token ( ch -- parser ) 1string token ; : (list-of) ( items separator repeat1? -- parser ) [ over 2seq ] dip [ 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 ; : exactly-n ( parser n -- parser' ) swap seq ; : at-most-n ( parser n -- parser' ) [ drop epsilon ] [ [ exactly-n ] [ 1 - at-most-n ] 2bi 2choice ] if-zero ; : at-least-n ( parser n -- parser' ) dupd exactly-n swap repeat0 2seq [ flatten-vectors ] action ; : from-m-to-n ( parser m n -- parser' ) [ [ exactly-n ] 2keep ] dip swap - at-most-n 2seq [ flatten-vectors ] action ; : pack ( begin body end -- parser ) [ hide ] [ ] [ hide ] tri* 3seq [ first ] action ; : surrounded-by ( parser begin end -- parser' ) [ token ] bi@ swapd pack ; : digit-parser ( -- parser ) [ digit? ] satisfy [ digit> ] action ; : integer-parser ( -- parser ) [ digit? ] satisfy repeat1 [ string>number ] action ; : string-parser ( -- 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 ;