aboutsummaryrefslogtreecommitdiff
path: root/grammars/bpeg.bp
blob: c9422a83a688d64a537527b5398446d6fd33f244 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# This is a file defining the BPEG grammar using BPEG syntax

Grammar: __ *(Def [__`;])%__ __ ($$ / @!={... => "Could not parse this code"})
Def: @name=id _ `: __ (
      @definition=extended-pat
    / $$ @!={=>"No definition for rule"}
    / @!={...>(`;/id_`:/$) => "Invalid definition: @0"})

# This is used for command line arguments:
String-pattern: ... % (Nodent / Escape / `\ pat [`;])

pat: simple-pat !(__("!="/"==")) / suffixed-pat
simple-pat: Upto-and / Dot / String / Chars / Nodent / Escape-range
    / Escape / Repeat / Optional / After / Before / Capture / Replace
    / Ref / parens

suffixed-pat: (
      Eq-pat
    / Not-eq-pat
)

Eq-pat: @first=pat__"=="__@second=pat
Not-eq-pat: @first=pat__"!="__@second=pat

Dot: `. !`.
String: (
        `" @s=*(Escape / !`".) (`" / @!={=> "Expected closing quote here"})
      / `' @s=*(Escape / !`'.) (`' / @!={=> "Expected closing quote here"})
    )
Chars: `` @+(Char/Char-range) % `,
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
Upto-and: 2-3`. [_@first=simple-pat] [__`%__@second=simple-pat]
Repeat: (
        @min='' `* @max=''
      / @min=int _ `- _ @max=int
      / @min=int _ `+   @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"})
Replace: `{ __ (
      [@replace-pat=extended-pat __] "=>" [__ @replacement=String]
    ) __ (`} / @!={=> "Expected closing brace here"})
Ref: @name=id !(_`:)

parens: `( __ extended-pat (__ `) / @!={=> "Expected closing parenthesis here"})

Chain: 2+@pat%__
Otherwise: 2+@(Chain/pat)%(__`/__)
extended-pat: Otherwise / Chain / pat

# Special-symbol rules:
_:  *(`  / \t)
__: *(`  / \t / \r / \n / comment)
$$: !$.
$:  !.
^^: !<$.
^:  !<.

id: "^^" / "^" / "__" / "_" / "$$" / "$" / "|" / `a-z,A-Z *`a-z,A-Z,0-9,-

line-comment: `# .. $
block-comment: "#("..")#" % block-comment

# Note: comments are undefined by default in regular BPEG
comment: block-comment / line-comment