Parser Result Function
Once a unit has matched, a result function asks something about what it
matched, or turns it into a number. The calls are written after the unit with
::, and they chain — each one acts on what the one before produced.
name = <A:Za:z>+;
t = name::part(3:4)::is("ed"); # are characters 3 and 4 "ed"?
There are two kinds.
A predicate asks a question and can only pass or fail the unit it is attached to. A producer answers with a number instead, and never fails anything — so it is only useful where a number is wanted.
Predicates
Function |
Passes when the matched text |
|---|---|
|
equals the argument |
|
does not equal the argument |
|
contains the argument |
t1 = name::is("Fred"); # equals "Fred"
t4a = name::not("Amber"); # is not "Amber"
t2 = name::subkind("Fr"); # contains "Fr"
The argument is a grammar, not a value — it is run over the text the unit matched, by the same machine that matched it. So anything that can parse can be an argument:
t4b = char::not(\x41); # a character literal
t4c = char::not(tex::oneof("hello")); # a text function
t4d = name::is(word); # another action
t4e = name::is(B+ C* "a"); # a whole series
Narrowing with part
part cuts the text down before the rest of the chain asks about it. It is
1-indexed and counts characters.
t3a = name::part(1); # the first character
t3b = name::part(1:4); # characters 1 through 4
t3c = name::part(2+); # character 2 to the end
t3d = name::part(1)::is("F"); # chained: is the first character "F"?
Producers
Producers take no parentheses, because they take no argument.
Function |
Answers with |
|---|---|
|
how many characters were matched |
|
the matched text read as a number; |
|
how many times a counter ran; |
c = name::char_count;
v = number::to_num;
i = <A:Z>+::iter_steps;
A producer can be compared against a number, which is how a chain ends in a question again:
exactly3 = name::char_count::is(3);
two_hundred = number::to_num::is(200); # so "0200" matches too
within = name::char_count::is(limit); # ... or against a numvar
Or captured into a variable:
C := (n::to_num => numvar v);
Where the counter goes
The counter can sit on either side of the chain, and the two mean different things.
a = char*::not(q); # is the WHOLE run different from q?
b = char::not(q)*; # is EACH character different from q?
b is almost always what you want. Put the counter after the chain and the
question is asked of every repetition; put it before and it is asked once, of
everything that matched.
alias q \x22;
quoted := q . char::not(q)* . q; # a quoted string
On a variable, not just a match
A result function does not have to follow a match. It works on a
texvar just as well, because a texvar holds a span of text and
that is all these functions need:
A := (word => texvar x) . {x::char_count == 3};
B := (word => texvar x) . x::subkind("ed");
That is often the clearer way to write a check that has to happen some distance from where the text was matched.
The other :: — semvar and scope
The same :: reaches a semvar and a
scope, and those calls are a different set from the ones
above. They are not asking about text that just matched; they are asking about
a set or a depth.
Call |
On |
Meaning |
|---|---|---|
|
a semvar |
match the earliest member added, not the longest |
|
a scope |
run the begin grammar and go one deeper |
|
a scope |
come back out, and forget what was added inside |
|
a semvar, inside a logic block |
is |
So name::first and name::is("x") read alike and are not alike: on a matched
unit is compares the text, on a semvar inside a logic block it asks about
membership.
See also
Every function named here is a reserved word. To stop the parse rather than fail a match, see System Functions.