91 lines
3.3 KiB
Plaintext
91 lines
3.3 KiB
Plaintext
# This is a file defining the BP grammar using BP syntax
|
|
#
|
|
# This is a complete definition of the grammar of BP grammar files, but it's
|
|
# mainly intended to be used as a proof-of-concept, and a stress-test for BP.
|
|
# The grammar files provided with BP are not otherwise intended to be full
|
|
# language grammars.
|
|
|
|
Grammar: __ *(Def [__`;])%__ __ [(!)(+(./\n) => "Could not parse this code")]
|
|
Def: @name=id __ `: __ (
|
|
@definition=extended-pat
|
|
/ $$ (!)=>"No definition for rule"
|
|
/ (!)(..%\n>(`;/id_`:/$) => "Invalid definition: @0"))
|
|
|
|
# This is used for command line arguments:
|
|
String-pattern: ..%(\n / Nodent / Identifier-char / Identifier-start / Escape / `\ pat [`;])$$
|
|
|
|
pat: simple-pat !(__("!~"/"~")) / suffixed-pat
|
|
simple-pat: Upto-and / Dot / Word-boundary/ String / Chars / Nodent
|
|
/ Identifier-char / Identifier-start / Escape-range
|
|
/ Escape / Repeat / Optional / No / After / Before / Capture / Error / Empty-replacement
|
|
/ Start-of-File / Start-of-Line / End-of-File / End-of-Line / Ref / parens
|
|
|
|
suffixed-pat: (
|
|
Match-pat
|
|
/ Not-match-pat
|
|
)
|
|
|
|
Match-pat: @first=(suffixed-pat / simple-pat)__"~"__@second=(pat / (!)=>"Expected pattern after '~'")
|
|
Not-match-pat: @first=(suffixed-pat / simple-pat)__"!~"__@second=(pat / (!)=>"Expected pattern after '!~'")
|
|
|
|
Dot: `. !`.
|
|
String: (
|
|
`" @s=.. (`" / $ (!)=>"Expected closing quote here")
|
|
/ `' @s=.. (`' / $ (!)=>"Expected closing quote here")
|
|
)
|
|
Chars: `` @+(Char-range/Char) % `,
|
|
Char-range: @low=. `- (@high=. / (!)=>"Expected a second character to form a character range")
|
|
Char: (@s=. / (!)=>"Expected a character following the '`'")
|
|
Escape-range: `\ @low=escape-sequence `- @high=escape-sequence
|
|
Escape: `\ (@s=escape-sequence
|
|
/ $ (!)=>"Backslashes are used for escape sequences, not splitting lines"
|
|
/ (!)(. *(Abc/`0-9) => "Invalid escape sequence: '@0'")
|
|
)
|
|
escape-sequence: (
|
|
`n,t,r,e,b,a,v
|
|
/ 1-3 `0-7
|
|
/ `x 2 `0-9,a-f,A-F
|
|
)
|
|
No: `! (__@pat / (!)=>"Expected a pattern after the exclamation mark")
|
|
Nodent: "\N"
|
|
Word-boundary: "\b"
|
|
Identifier-char: "\i"
|
|
Identifier-start: "\I"
|
|
Upto-and: ".." [__(`%/`=)__@second=simple-pat] [__@first=simple-pat]
|
|
Repeat: (
|
|
@min=(=>'0') (`*=>"-") @max=(=>'∞')
|
|
/ @min=int __ `- __ @max=int
|
|
/ @min=(int / =>'1') __ (`+=>"-") @max=(=>'∞')
|
|
/ @min=@max=int
|
|
) __ @repeat-pat=pat [__`%__@sep=pat]
|
|
Optional: `[ __ extended-pat (__`] / (!)=>"Expected closing square bracket here")
|
|
After: `< __ pat
|
|
Before: `> __ pat
|
|
Capture: `@ [__ @capture-name=(id/`!) __ !"=>" `=] __ (@capture=pat / (!)=>"Expected pattern to capture")
|
|
Error: "(!)" @pat=[__ (Replace / Chain / pat)]
|
|
Replace: (
|
|
@replace-pat=(Replace / Chain / pat) __ "=>" (__ @replacement=String / (!)=>"Expected replacement string")
|
|
)
|
|
Empty-replacement: (
|
|
@replace-pat=(=>"''") "=>" (__ @replacement=String / (!)=>"Expected replacement string")
|
|
)
|
|
Ref: @name=id !(__`:)
|
|
Start-of-File: "^^"
|
|
Start-of-Line: "^"
|
|
End-of-File: "$$"
|
|
End-of-Line: "$"
|
|
|
|
parens: `( __ extended-pat (__ `) / (!)=>"Expected closing parenthesis here")
|
|
|
|
Chain: 2+@(pat !(__"=>") / Replace)%__
|
|
Otherwise: 2+@(Replace / Chain / pat)%(__`/__)
|
|
extended-pat: Otherwise / Replace / Chain / pat
|
|
|
|
# Special-symbol rules:
|
|
_: *(` / \t)
|
|
__: *(` / \t / \r / \n / comment)
|
|
|
|
id: "__" / "_" / `a-z,A-Z *`a-z,A-Z,0-9,-
|
|
|
|
comment: `# .. $
|