combinators.nim
4.07 KB
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import petitparser, context
# DelegateParser
type
DelegateParser* = ref object of Parser
delegate*: Parser
proc newDelegateParser*(delegate: Parser not nil): DelegateParser =
DelegateParser(delegate: delegate)
method parseOn*(self: DelegateParser, context: Context): Result =
self.delegate.parseOn(context)
method replace*(self: DelegateParser, source, target: Parser) =
procCall(Parser(self).replace(source, target))
if delegate == source:
delegate = target
method getChildren(self: DelegateParser): seq[Parser] =
@[delegate]
method copy(self: DelegateParser): Parser =
newDelegateParser(self.delegate)
## A parser that optionally parsers its delegate, or answers nil.
type
OptionalParser* = ref object of DelegateParser
otherwise*: RootRef
proc newOptionalParser*(delegate: Parser, otherwise: RootRef): OptionalParser =
OptionalParser(delegate: delegate, otherwise: otherwise)
# public OptionalParser(Parser delegate, Object otherwise) {
# super(delegate);
# this.otherwise = otherwise;
# }
method parseOn*(self: OptionalParser, context: Context): Result =
result = self.delegate.parseOn(context)
if result.isSuccess:
return
current.success(elements)
# public Result parseOn(Context context) {
# Result result = delegate.parseOn(context);
# if (result.isSuccess()) {
# return result;
# } else {
# return context.success(otherwise);
# }
# }
method hasEqualProperties*(self: OptionalParser, other: Parser): bool =
return true
# protected boolean hasEqualProperties(Parser other) {
# return super.hasEqualProperties(other) &&
# Objects.equals(otherwise, ((OptionalParser) other).otherwise);
# }
method copy*(self: OptionalParser): Parser =
newOptionalParser(self.delegate, self.otherwise)
# @Override
# public Parser copy() {
# return new OptionalParser(delegate, otherwise);
# }
# Abstract parser that parses a list of things in some way (to be specified by the subclasses).
type
ListParser* = ref object of Parser
parsers*: seq[Parser]
#proc newListParser*(parsers: seq[Parser] not nil): ListParser =
# ListParser(parsers: parsers)
method replace*(self: ListParser, source, target: Parser) =
procCall(Parser(self).replace(source, target))
for i in 0..high(parsers):
if parsers[i] == source:
parsers[i] = target
# public void replace(Parser source, Parser target) {
# super.replace(source, target);
# for (int i = 0; i < parsers.length; i++) {
# if (parsers[i] == source) {
# parsers[i] = target;
# }
# }
# }
method getChildren(self: ListParser): seq[Parser] =
self.parsers
# public List<Parser> getChildren() {
# return Arrays.asList(parsers);
# }
# A parser that parses a sequence of parsers.
type
SequenceParser* = ref object of ListParser
method parseOn*(self: SequenceParser, context: Context): Result =
var
current = context
elements = newSeq[auto](self.parsers.len)
for parser in self.parsers:
result = parser.parseOn(current)
if result.isFailure:
return
elements.add(result.get())
current = result
current.success(elements)
# public Result parseOn(Context context) {
# Context current = context;
# List<Object> elements = new ArrayList<>(parsers.length);
# for (Parser parser : parsers) {
# Result result = parser.parseOn(current);
# if (result.isFailure()) {
# return result;
# }
# elements.add(result.get());
# current = result;
# }
# return current.success(elements);
# }
method seq*(self: SequenceParser, others: varargs[Parser]): Parser =
newSequenceParser(self.parsers & others)
# let all = newSeq[Parser](self.parsers.len + others.len)
# public Parser seq(Parser... others) {
# Parser[] array = Arrays.copyOf(parsers, parsers.length + others.length);
# System.arraycopy(others, 0, array, parsers.length, others.length);
# return new SequenceParser(array);
# }
method copy*(self: SequenceParser): Parser =
newSequenceParser(@[] & self.parsers)
# @Override
# public Parser copy() {
# return new SequenceParser(Arrays.copyOf(parsers, parsers.length));
# }
#}