forked from jamiejennings/rosie-pattern-language
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrpl-core.rpl
96 lines (77 loc) · 3.37 KB
/
rpl-core.rpl
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
---- -*- Mode: rpl; -*-
----
---- rpl-core.rpl Rosie Pattern Language definition for Rosie Pattern Language
----
---- © Copyright IBM Corporation 2016.
---- LICENSE: MIT License (https://opensource.org/licenses/mit-license.html)
---- AUTHOR: Jamie A. Jennings
alias newline = {"\n"} -- raw mode just to suppress compiler warning
alias comment = { "--" {!newline .}* {newline / $} }
alias ignore = { { [[:space:]] / comment }* }
alias id_char = { [[:alnum:]] / [[_]] }
alias id = { [[:alpha:]] id_char* }
identifier = { { id {[[.]]id}* } -- hierarchical identifier name
/ [[.]] -- a single dot
/ [[$]] -- a single dollar sign
/ [[~]] -- a single tilde
}
alias dquote = { [[\"]] }
alias esc = { [[\\]] }
literal = { {!{esc/dquote} .} / {esc .} }*
alias quoted_string = { dquote literal dquote }
star = { [[*]] }
question = { [[?]] }
plus = { [[+]] }
alias end_token = { "end" !id_char }
alias keyword_list = { "alias" / "grammar" / "end" }
keyword = { keyword_list !id_char }
-- it is important that an error consume at least one character here.
-- as a tactic for continuing to parse after an error , we will skip to eol and try to continue.
rest_of_line = { {!newline .}+ ignore }
syntax_error = { rest_of_line }
complement = "^"
character = { {!esc !"[" !"^" !"]" .} / {esc .} }
range = { complement? character [[-]] !"]" character }
charlist = { complement? {!"]" character}+ } -- cannot be empty
name = {!":" .}+
named_charset = { complement? name }
alias one_charset = { "[" { ":" named_charset ":]" } /
{ range "]" } /
{ charlist "]" } /
syntax_error
}
charset_exp = { "[" complement? ignore (one_charset ignore)+ "]" } / one_charset
low = [[:digit:]]* -- an int or nothing
high = [[:digit:]]*
repetition = { "{" ignore low ignore "," ignore high ignore "}" }
alias quantifier = star / question / plus / repetition
assignment_prefix = identifier ignore "="
statement_prefix = {keyword / assignment_prefix}
alias slash = { [[/]] }
alias open = { [[(]] }
alias openraw = { [[{]] }
alias close = { [[)]] }
alias closeraw = { [[}]] }
negation = { [[!]] }
lookat = { [[@]] }
alias predicate_symbol = { negation / lookat }
grammar
alias expression = {ignore { syntax_error / choice / sequence / quantified_exp / plain_exp} }
syntax_error = { statement_prefix rest_of_line }
choice = { {quantified_exp / plain_exp} ignore slash expression }
sequence = { {quantified_exp / plain_exp} {ignore !statement_prefix expression}+ }
alias plain_exp = { ignore
{ identifier / quoted_string / raw / cooked / charset_exp / predicate } }
quantified_exp = { plain_exp ignore quantifier }
cooked = { open expression+ ignore close }
raw = { openraw expression+ ignore closeraw }
predicate = { predicate_symbol ignore {quantified_exp / plain_exp} }
end
grammar
alias statement = { alias_ / grammar_ / assignment_ }
alias_ = { "alias" ignore identifier ignore "=" expression }
grammar_ = { "grammar" { ignore { alias_ / assignment_ } }+ ignore end_token }
-- assignment_ = { identifier ignore "=" { expression / syntax_error } }
assignment_ = { identifier ignore "=" expression }
end
rpl = {ignore {statement / expression / syntax_error}}