-
Notifications
You must be signed in to change notification settings - Fork 21
Description
Here's a request to all NPeg users: I'm looking for some ideas and feedback for the proper design of the API for grammar code blocks. At this time the available functions feel ad hoc and scattered, and I don't dare to call this v1.0 before a better interface is in place.
Here is a list of things a code block capture can do, and how this works now:
-
Access captures: when a code block executes, all closed captures that were made inside the rule, and the code block capture itself are available to the code block as the variable
capturewhich is of typeseq[Capture]. TheCaptureobject has a few public members that can be used from the code block:sis the captured string andsiis the index into the original subject where the capture was matched. The capture stringssare also accessible through a sugar macro that rewrites the code block as$n:capture[0]or$0is the total capture of the rulecapture[1..]or$1are the explicit string captures inside the rule
-
Force a rule to fail:
- code blocks have access to a proc
fail()which will cause the match to fail - this can be used to validate matches with Nim code, for example to check integer ranges, enum values, or symbols that were captured earlier. - code blocks have acecss to a proc
validate(b: bool), which is nothing more thenif not b: fail()
For example:
- code blocks have access to a proc
uint8 <- >Digit[1..3]:
let v = parseInt($a)
validate v>=0 and v<=255 - Perform matching in Nim code: the internal match state is implicitly available to the code block capture, which can (ab)use that to do matching in Nim code: the code block can see and adjust the match index, and indicate success or failure, for example:
let p = peg foo:
foo <- "ba" * die * "da"
die <- 0:
if si < s.len-3 and if cast[string](s[si..si+2]) == "die":
si += 3
else:
fail()
echo p.match("badieda")All of the above features were introduced in NPeg one at a time, growing the API lacking a proper design.
My question: does the above feel as kludgy as I think it is, or is it fine as it is now? Any ideas for improvement or what this should look like?