2007-11-27 00:13:36 -05:00
|
|
|
! Copyright (C) 2007 Chris Double.
|
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2007-11-27 19:03:16 -05:00
|
|
|
USING: kernel parser words arrays strings math.parser sequences quotations vectors namespaces peg ;
|
2007-11-27 00:13:36 -05:00
|
|
|
IN: peg.ebnf
|
|
|
|
|
|
|
|
TUPLE: ebnf-non-terminal symbol ;
|
|
|
|
TUPLE: ebnf-terminal symbol ;
|
|
|
|
TUPLE: ebnf-choice options ;
|
2007-11-27 16:28:28 -05:00
|
|
|
TUPLE: ebnf-sequence elements ;
|
2007-11-27 17:33:21 -05:00
|
|
|
TUPLE: ebnf-repeat0 group ;
|
2007-11-27 16:28:28 -05:00
|
|
|
TUPLE: ebnf-rule symbol elements ;
|
2007-11-27 19:03:16 -05:00
|
|
|
TUPLE: ebnf-action word ;
|
2007-11-27 17:25:34 -05:00
|
|
|
TUPLE: ebnf rules ;
|
2007-11-27 00:13:36 -05:00
|
|
|
|
|
|
|
C: <ebnf-non-terminal> ebnf-non-terminal
|
|
|
|
C: <ebnf-terminal> ebnf-terminal
|
|
|
|
C: <ebnf-choice> ebnf-choice
|
2007-11-27 16:28:28 -05:00
|
|
|
C: <ebnf-sequence> ebnf-sequence
|
2007-11-27 17:33:21 -05:00
|
|
|
C: <ebnf-repeat0> ebnf-repeat0
|
2007-11-27 16:28:28 -05:00
|
|
|
C: <ebnf-rule> ebnf-rule
|
2007-11-27 18:50:04 -05:00
|
|
|
C: <ebnf-action> ebnf-action
|
2007-11-27 17:25:34 -05:00
|
|
|
C: <ebnf> ebnf
|
2007-11-27 00:13:36 -05:00
|
|
|
|
|
|
|
GENERIC: ebnf-compile ( ast -- quot )
|
|
|
|
|
|
|
|
M: ebnf-terminal ebnf-compile ( ast -- quot )
|
|
|
|
[
|
|
|
|
ebnf-terminal-symbol , \ token ,
|
|
|
|
] [ ] make ;
|
|
|
|
|
2007-11-27 17:07:17 -05:00
|
|
|
M: ebnf-non-terminal ebnf-compile ( ast -- quot )
|
|
|
|
[
|
2007-11-27 17:25:34 -05:00
|
|
|
ebnf-non-terminal-symbol , \ in , \ get , \ lookup , \ execute ,
|
2007-11-27 17:07:17 -05:00
|
|
|
] [ ] make ;
|
|
|
|
|
2007-11-27 00:13:36 -05:00
|
|
|
M: ebnf-choice ebnf-compile ( ast -- quot )
|
|
|
|
[
|
|
|
|
[
|
|
|
|
ebnf-choice-options [
|
|
|
|
ebnf-compile ,
|
|
|
|
] each
|
|
|
|
] { } make ,
|
2007-11-27 16:28:28 -05:00
|
|
|
[ call ] , \ map , \ choice ,
|
|
|
|
] [ ] make ;
|
|
|
|
|
|
|
|
M: ebnf-sequence ebnf-compile ( ast -- quot )
|
|
|
|
[
|
|
|
|
[
|
|
|
|
ebnf-sequence-elements [
|
|
|
|
ebnf-compile ,
|
|
|
|
] each
|
|
|
|
] { } make ,
|
|
|
|
[ call ] , \ map , \ seq ,
|
2007-11-27 00:13:36 -05:00
|
|
|
] [ ] make ;
|
|
|
|
|
2007-11-27 17:33:21 -05:00
|
|
|
M: ebnf-repeat0 ebnf-compile ( ast -- quot )
|
|
|
|
[
|
|
|
|
ebnf-repeat0-group ebnf-compile % \ repeat0 ,
|
|
|
|
] [ ] make ;
|
|
|
|
|
2007-11-27 17:07:17 -05:00
|
|
|
M: ebnf-rule ebnf-compile ( ast -- quot )
|
|
|
|
[
|
|
|
|
dup ebnf-rule-symbol , \ in , \ get , \ create ,
|
|
|
|
ebnf-rule-elements ebnf-compile , \ define-compound ,
|
|
|
|
] [ ] make ;
|
|
|
|
|
2007-11-27 18:50:04 -05:00
|
|
|
M: ebnf-action ebnf-compile ( ast -- quot )
|
|
|
|
[
|
2007-11-27 19:03:16 -05:00
|
|
|
ebnf-action-word search 1quotation , \ action ,
|
2007-11-27 18:50:04 -05:00
|
|
|
] [ ] make ;
|
|
|
|
|
|
|
|
M: vector ebnf-compile ( ast -- quot )
|
|
|
|
[
|
|
|
|
[ ebnf-compile % ] each
|
|
|
|
] [ ] make ;
|
|
|
|
|
|
|
|
M: f ebnf-compile ( ast -- quot )
|
|
|
|
drop [ ] ;
|
|
|
|
|
2007-11-27 17:25:34 -05:00
|
|
|
M: ebnf ebnf-compile ( ast -- quot )
|
|
|
|
[
|
|
|
|
ebnf-rules [
|
|
|
|
ebnf-compile %
|
|
|
|
] each
|
|
|
|
] [ ] make ;
|
|
|
|
|
2007-11-27 00:13:36 -05:00
|
|
|
DEFER: 'rhs'
|
|
|
|
|
|
|
|
: 'non-terminal' ( -- parser )
|
|
|
|
CHAR: a CHAR: z range repeat1 [ >string <ebnf-non-terminal> ] action ;
|
|
|
|
|
|
|
|
: 'terminal' ( -- parser )
|
2007-11-27 18:50:04 -05:00
|
|
|
"'" token hide [ CHAR: ' = not ] satisfy repeat1 "'" token hide 3array seq [ first >string <ebnf-terminal> ] action ;
|
2007-11-27 00:13:36 -05:00
|
|
|
|
|
|
|
: 'element' ( -- parser )
|
|
|
|
'non-terminal' 'terminal' 2array choice ;
|
|
|
|
|
|
|
|
: 'sequence' ( -- parser )
|
2007-11-27 16:28:28 -05:00
|
|
|
'element' sp
|
2007-11-27 21:14:11 -05:00
|
|
|
repeat1 [
|
|
|
|
dup length 1 = [ first ] [ <ebnf-sequence> ] if
|
|
|
|
] action ;
|
2007-11-27 00:13:36 -05:00
|
|
|
|
2007-11-27 21:14:11 -05:00
|
|
|
: 'choice' ( -- parser )
|
|
|
|
'sequence' sp "|" token sp list-of [
|
|
|
|
dup length 1 = [ first ] [ <ebnf-choice> ] if
|
|
|
|
] action ;
|
|
|
|
|
2007-11-27 00:13:36 -05:00
|
|
|
: 'repeat0' ( -- parser )
|
|
|
|
"{" token sp hide
|
|
|
|
[ 'rhs' sp ] delay
|
|
|
|
"}" token sp hide
|
2007-11-27 17:33:21 -05:00
|
|
|
3array seq [ first <ebnf-repeat0> ] action ;
|
2007-11-27 00:13:36 -05:00
|
|
|
|
2007-11-27 18:50:04 -05:00
|
|
|
: 'action' ( -- parser )
|
|
|
|
"=>" token hide
|
2007-11-27 19:03:16 -05:00
|
|
|
[ blank? ] satisfy ensure-not [ drop t ] satisfy 2array seq [ first ] action repeat1 [ >string ] action sp
|
|
|
|
2array seq [ first <ebnf-action> ] action ;
|
2007-11-27 18:50:04 -05:00
|
|
|
|
2007-11-27 00:13:36 -05:00
|
|
|
: 'rhs' ( -- parser )
|
|
|
|
'repeat0'
|
2007-11-27 16:28:28 -05:00
|
|
|
'choice'
|
2007-11-27 21:14:11 -05:00
|
|
|
2array choice 'action' sp optional 2array seq ;
|
2007-11-27 18:50:04 -05:00
|
|
|
|
2007-11-27 00:13:36 -05:00
|
|
|
: 'rule' ( -- parser )
|
2007-11-27 16:28:28 -05:00
|
|
|
'non-terminal' [ ebnf-non-terminal-symbol ] action
|
|
|
|
"=" token sp hide
|
2007-11-27 00:13:36 -05:00
|
|
|
'rhs'
|
2007-11-27 16:28:28 -05:00
|
|
|
3array seq [ first2 <ebnf-rule> ] action ;
|
2007-11-27 17:25:34 -05:00
|
|
|
|
|
|
|
: 'ebnf' ( -- parser )
|
2007-11-27 17:46:06 -05:00
|
|
|
'rule' sp "." token sp hide list-of [ <ebnf> ] action ;
|
2007-11-27 17:25:34 -05:00
|
|
|
|
|
|
|
: ebnf>quot ( string -- quot )
|
|
|
|
'ebnf' parse [
|
|
|
|
parse-result-ast ebnf-compile
|
|
|
|
] [
|
|
|
|
f
|
2007-11-27 17:46:06 -05:00
|
|
|
] if* ;
|
|
|
|
|
2007-11-27 18:52:05 -05:00
|
|
|
: <EBNF "EBNF>" parse-tokens " " join ebnf>quot call ; parsing
|