More error handling for pegs
parent
00827d3b12
commit
e14bb84a5a
|
@ -1,36 +1,47 @@
|
||||||
! Copyright (C) 2007, 2008 Chris Double.
|
! Copyright (C) 2007, 2008 Chris Double.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: kernel sequences strings fry namespaces math assocs shuffle debugger io
|
USING: kernel sequences strings fry namespaces math assocs shuffle debugger io
|
||||||
vectors arrays math.parser math.order
|
vectors arrays math.parser math.order vectors combinators combinators.lib
|
||||||
unicode.categories compiler.units parser
|
sets unicode.categories compiler.units parser
|
||||||
words quotations effects memoize accessors locals effects splitting ;
|
words quotations effects memoize accessors locals effects splitting ;
|
||||||
IN: peg
|
IN: peg
|
||||||
|
|
||||||
USE: prettyprint
|
USE: prettyprint
|
||||||
|
|
||||||
TUPLE: parse-result remaining ast ;
|
TUPLE: parse-result remaining ast ;
|
||||||
TUPLE: parse-error details ;
|
TUPLE: parse-error position messages ;
|
||||||
TUPLE: error-details remaining message ;
|
|
||||||
TUPLE: parser id compiled ;
|
TUPLE: parser id compiled ;
|
||||||
M: parser equal? [ id>> ] bi@ = ;
|
M: parser equal? [ id>> ] bi@ = ;
|
||||||
|
|
||||||
M: parser hashcode* id>> hashcode* ;
|
M: parser hashcode* id>> hashcode* ;
|
||||||
|
|
||||||
C: <parse-result> parse-result
|
C: <parse-result> parse-result
|
||||||
C: <error-details> error-details
|
C: <parse-error> parse-error
|
||||||
C: <parser> parser
|
C: <parser> parser
|
||||||
|
|
||||||
SYMBOL: errors
|
SYMBOL: error-stack
|
||||||
|
|
||||||
: <parse-error> ( -- parse-error )
|
: (merge-errors) ( a b -- c )
|
||||||
V{ } clone parse-error boa ;
|
{
|
||||||
|
{ [ over position>> not ] [ nip ] }
|
||||||
|
{ [ dup position>> not ] [ drop ] }
|
||||||
|
[ 2dup [ position>> ] bi@ <=> {
|
||||||
|
{ +lt+ [ nip ] }
|
||||||
|
{ +gt+ [ drop ] }
|
||||||
|
{ +eq+ [ messages>> over messages>> union [ position>> ] dip <parse-error> ] }
|
||||||
|
} case
|
||||||
|
]
|
||||||
|
} cond ;
|
||||||
|
|
||||||
|
: merge-errors ( -- )
|
||||||
|
error-stack get dup length 1 > [
|
||||||
|
dup pop over pop swap (merge-errors) swap push
|
||||||
|
] [
|
||||||
|
drop
|
||||||
|
] if ;
|
||||||
|
|
||||||
: add-error ( remaining message -- )
|
: add-error ( remaining message -- )
|
||||||
errors get [
|
<parse-error> error-stack get push ;
|
||||||
[ <error-details> ] [ details>> ] bi* push
|
|
||||||
] [
|
|
||||||
2drop
|
|
||||||
] if* ;
|
|
||||||
|
|
||||||
SYMBOL: ignore
|
SYMBOL: ignore
|
||||||
|
|
||||||
|
@ -218,7 +229,7 @@ C: <head> peg-head
|
||||||
input set
|
input set
|
||||||
0 pos set
|
0 pos set
|
||||||
f lrstack set
|
f lrstack set
|
||||||
<parse-error> errors set
|
V{ } clone error-stack set
|
||||||
H{ } clone heads set
|
H{ } clone heads set
|
||||||
H{ } clone packrat set
|
H{ } clone packrat set
|
||||||
] H{ } make-assoc swap bind ; inline
|
] H{ } make-assoc swap bind ; inline
|
||||||
|
@ -269,7 +280,7 @@ SYMBOL: delayed
|
||||||
] with-compilation-unit ;
|
] with-compilation-unit ;
|
||||||
|
|
||||||
: compiled-parse ( state word -- result )
|
: compiled-parse ( state word -- result )
|
||||||
swap [ execute [ errors get throw ] unless* ] with-packrat ; inline
|
swap [ execute [ error-stack get throw ] unless* ] with-packrat ; inline
|
||||||
|
|
||||||
: parse ( input parser -- result )
|
: parse ( input parser -- result )
|
||||||
dup word? [ compile ] unless compiled-parse ;
|
dup word? [ compile ] unless compiled-parse ;
|
||||||
|
@ -298,9 +309,9 @@ TUPLE: token-parser symbol ;
|
||||||
: parse-token ( input string -- result )
|
: parse-token ( input string -- result )
|
||||||
#! Parse the string, returning a parse result
|
#! Parse the string, returning a parse result
|
||||||
dup >r ?head-slice [
|
dup >r ?head-slice [
|
||||||
r> <parse-result>
|
r> <parse-result> f f add-error
|
||||||
] [
|
] [
|
||||||
drop input-slice "Expected token '" r> append "'" append add-error f
|
drop input-slice input-from "Expected token '" r> append "'" append 1vector add-error f
|
||||||
] if ;
|
] if ;
|
||||||
|
|
||||||
M: token-parser (compile) ( parser -- quot )
|
M: token-parser (compile) ( parser -- quot )
|
||||||
|
@ -366,7 +377,8 @@ TUPLE: seq-parser parsers ;
|
||||||
M: seq-parser (compile) ( parser -- quot )
|
M: seq-parser (compile) ( parser -- quot )
|
||||||
[
|
[
|
||||||
[ input-slice V{ } clone <parse-result> ] %
|
[ input-slice V{ } clone <parse-result> ] %
|
||||||
parsers>> [ compiled-parser 1quotation , \ parse-seq-element , ] each
|
parsers>> unclip compiled-parser 1quotation , \ parse-seq-element , [
|
||||||
|
compiled-parser 1quotation [ merge-errors ] compose , \ parse-seq-element , ] each
|
||||||
] [ ] make ;
|
] [ ] make ;
|
||||||
|
|
||||||
TUPLE: choice-parser parsers ;
|
TUPLE: choice-parser parsers ;
|
||||||
|
@ -374,7 +386,8 @@ TUPLE: choice-parser parsers ;
|
||||||
M: choice-parser (compile) ( parser -- quot )
|
M: choice-parser (compile) ( parser -- quot )
|
||||||
[
|
[
|
||||||
f ,
|
f ,
|
||||||
parsers>> [ compiled-parser 1quotation , \ unless* , ] each
|
parsers>> [ compiled-parser ] map
|
||||||
|
unclip 1quotation , \ unless* , [ 1quotation [ merge-errors ] compose , \ unless* , ] each
|
||||||
] [ ] make ;
|
] [ ] make ;
|
||||||
|
|
||||||
TUPLE: repeat0-parser p1 ;
|
TUPLE: repeat0-parser p1 ;
|
||||||
|
|
Loading…
Reference in New Issue