-
Notifications
You must be signed in to change notification settings - Fork 11
User Data
User data is an object that is passed as part of the parser state during parsing. It can be any type of object, however, for your own sanity, the user data should be immutable.
If you are looking to provide custom state for your parser, user data is almost always the correct way to go. For position aware customizable state see position.
The included operations for running parsers such as parse.run
and parse.runStream
include an optional user data argument.
parse.run(my_parser, "some input", my_user_data);
parse.test(my_parser, "some input", my_user_data);
parse.parse(my_parser, "some input", my_user_data, ok_callback, err_callback);
For the versions of the run operations that instead take a parser state, simply construct the state with the initial user data:
parse.runState(my_parser,
new parse.ParserState(
my_input_stream,
parse.Position.initial,
my_user_data));
You can always explicitly pass null
if you don't care about user data too.
parse.run(my_parser, "some input", null);
parse.parse(my_parser, "some input", null, ok_callback, err_callback);
There are three state interaction parser that you must use to get, set, or modify user data:
Succeeds with the current [user state][user-state].
parse.run(
parse.getState,
"abc",
'user state'); // returns 'user state'
Sets the user data to s
. Succeeds with s
.
parse.run(
parse.setState('new user state'),
"abc",
'user state'); // returns 'new user state'
#### parse.modifyState(f)
Modify the user data using function f, succeeding the result and setting the state to be the result.
parse.run(
parse.sequence(
parse.modifyState(\x -> x + 10),
parse.modifyState(\x -> x / 2),
parse.getState)
"abc",
0); // returns 5
There are two ways to extract the user data from a parser after it has run.
The preferred approach is to use parsers to extract (and possibly combine) the user data.
// Parser the sums the digits is parses, storing this in the user data
var num = parse_text.digit.map(\x -> ++x);
var sum = num.chain(\x ->
parse.modifyState \ ud -> ud + x);
var sums = parse.many(sum);
// extract the result from the user data.
var adder = parse.next(
sums,
parse.getState);
parse.run(adder, "173", 0); // 11
This works best when you only care about success user data and not failure user data, although you can certainly pass user data though failure paths as well.
The alternative is the use parse.parse
and extract the resulting parser state object, and then extract the user data from the state. This is more complex is not encouraged.
var sums = ...; // from above
parse.parse(
sums,
new parse.ParserState(stream.from("173"), parse.Position.initial, 0),
\x state -> console.log(state.userState),
\x state -> console.error(state.userState))