Skip to content

Commit 43de27c

Browse files
committed
add parser feature grammar expansion WIP
1 parent b4c7634 commit 43de27c

File tree

4 files changed

+198
-93
lines changed

4 files changed

+198
-93
lines changed

lib/ebnf.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,12 @@ defmodule EBNF do
149149

150150
"*" ->
151151
# S' ::= S S' |
152+
# from == 0 to--
152153
[alternate: [factor, {:identifier, [next_rule_name]}, "|", {:empty, []}]]
153154

154155
"+" ->
155156
# S' ::= S S' | S
157+
# from-- to--
156158
[alternate: [factor, {:identifier, [next_rule_name]}, "|", factor]]
157159
end
158160

lib/ebnf/parser.ex

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,20 @@ defmodule EBNF.Parser do
22
@moduledoc false
33

44
import NimbleParsec
5-
import EBNF.Parser.Helpers
5+
6+
from_to =
7+
ignore(string("{"))
8+
|> integer(min: 1)
9+
|> ignore(string(","))
10+
|> integer(min: 1)
11+
|> ignore(string("}"))
12+
|> tag(:from_to)
13+
14+
times =
15+
ignore(string("{"))
16+
|> integer(min: 1)
17+
|> ignore(string("}"))
18+
|> tag(:times)
619

720
whitespace = repeat(choice([string(" "), string("\n"), string("\t")]))
821

@@ -25,8 +38,16 @@ defmodule EBNF.Parser do
2538
choice([
2639
string(~S( )) |> replace(?\s),
2740
string(~S(\t)) |> replace(?\t),
41+
string("\t") |> replace(?\t),
2842
string(~S(\n)) |> replace(?\n),
43+
string("\n") |> replace(?\n),
44+
string("\r") |> replace(?\r),
2945
string(~S(\\)) |> replace(?\\),
46+
string("\\") |> replace(?\\),
47+
string("\"") |> replace(?\"),
48+
string("\d") |> replace(?\d),
49+
string("\0") |> replace(?\0),
50+
string("\x1F") |> replace(~s(\x1F)),
3051
ascii_char([?a..?z, ?A..?Z, ?0..?9, ?_, ?-, ?+, ?*, ?/])
3152
])
3253
|> tag(:char)
@@ -37,11 +58,20 @@ defmodule EBNF.Parser do
3758
|> concat(char)
3859
|> tag(:range)
3960

61+
62+
4063
range_or_char = choice([range, char])
4164

65+
negation =
66+
ignore(string("^"))
67+
|> concat(range_or_char)
68+
|> tag(:negation)
69+
70+
negation_range_or_char = choice([negation, range, char])
71+
4272
character_set =
4373
ignore(string("["))
44-
|> times(range_or_char, min: 1)
74+
|> times(negation_range_or_char, min: 1)
4575
|> ignore(string("]"))
4676
|> tag(:character_set)
4777

@@ -50,7 +80,7 @@ defmodule EBNF.Parser do
5080
|> tag(:terminal)
5181

5282
identifier =
53-
ascii_string([?a..?z, ?A..?Z, ?0..?9, ?_], min: 1)
83+
ascii_string([?a..?z, ?A..?Z, ?0..?9, ?_, ?-], min: 1)
5484
|> tag(:identifier)
5585

5686
grouping =
@@ -63,10 +93,13 @@ defmodule EBNF.Parser do
6393

6494
factor =
6595
choice([identifier, terminal, grouping])
66-
|> repeatable()
96+
|> then(&choice([
97+
tag(concat(&1,choice([string("*"), string("+"), string("?"), from_to, times])),:repetition),
98+
&1
99+
]))
67100
|> ignore(repeat(choice([string(" "), string("\t")])))
68101

69-
term = times(factor, min: 1)
102+
term = times(factor, min: 0)
70103

71104
choice_separator =
72105
ignore(repeat(string(" ")))

lib/ebnf/parser/helpers.ex

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)