Accept 'acc' and 'drop' as token functions

'acc': accumulate tokens in the parser's state. This was previously
available by not specifying a token function.

'drop': just drop tokens when they're ready.
This commit is contained in:
Jean-Sébastien Pédron 2011-10-18 16:17:24 +02:00
parent ec169974b5
commit b04c7d4729
3 changed files with 21 additions and 9 deletions

View File

@ -13,7 +13,7 @@
-type yaml_parser_option() :: {default_tags, [{tag_uri(), tag_prefix()}]} -type yaml_parser_option() :: {default_tags, [{tag_uri(), tag_prefix()}]}
| {document_version, document_version()} | {document_version, document_version()}
| {io_blocksize, pos_integer()} | {io_blocksize, pos_integer()}
| {token_fun, yaml_parser_token_fun()}. | {token_fun, yaml_parser_token_fun() | acc | drop}.
%% ------------------------------------------------------------------- %% -------------------------------------------------------------------
%% Main record to store the scanner state. %% Main record to store the scanner state.
@ -121,7 +121,11 @@
%% parameters: %% parameters:
%% o the block-context indentation prefixes (a stack); %% o the block-context indentation prefixes (a stack);
%% o the level of flow-context nesting (a stack too). %% o the level of flow-context nesting (a stack too).
stream_state :: fun((#yaml_parser{}) -> stream_state :: fun((string(),
pos_integer(),
pos_integer(),
non_neg_integer(),
#yaml_parser{}) ->
{ok, #yaml_parser{}} {ok, #yaml_parser{}}
| {continue, #yaml_parser{}} | {continue, #yaml_parser{}}
| none()), | none()),
@ -160,7 +164,7 @@
%% %%
%% Callbacks. %% Callbacks.
token_fun :: yaml_parser_token_fun() | undefined, token_fun = acc :: yaml_parser_token_fun() | acc | drop,
%% List of scanned tokens with counters. %% List of scanned tokens with counters.
tokens = [] :: [yaml_token()], tokens = [] :: [yaml_token()],

View File

@ -47,7 +47,7 @@ last_chunk(Parser, More_Data) ->
get_docs(Parser) -> get_docs(Parser) ->
case yaml_parser:get_token_fun(Parser) of case yaml_parser:get_token_fun(Parser) of
undefined -> Not_Fun when Not_Fun == acc orelse Not_Fun == drop ->
Error = #yaml_parsing_error{ Error = #yaml_parsing_error{
name = token_fun_cleared name = token_fun_cleared
}, },

View File

@ -240,7 +240,7 @@ new(Source, Options) ->
source = Source, source = Source,
options = Options, options = Options,
stream_state = fun start_stream/5, stream_state = fun start_stream/5,
token_fun = proplists:get_value(token_fun, Options) token_fun = proplists:get_value(token_fun, Options, acc)
}. }.
next_chunk(Parser, <<>>, false) -> next_chunk(Parser, <<>>, false) ->
@ -3930,21 +3930,25 @@ handle_tag_property(Parser, Token) ->
do_emit_token(Parser, Token). do_emit_token(Parser, Token).
do_emit_token( do_emit_token(
#yaml_parser{token_fun = undefined, #yaml_parser{token_fun = Not_Fun,
tks_queued = Queued, tks_first_idx = First, tks_queued = Queued, tks_first_idx = First,
tks_emitted = Emitted, tks_ready = Ready} = Parser, tks_emitted = Emitted, tks_ready = Ready} = Parser,
Token) -> Token) when Not_Fun == acc orelse Not_Fun == drop ->
%% The anchor was already counted when first removed from the queue. %% The anchor was already counted when first removed from the queue.
{Queued1, First1} = case ?TOKEN_NAME(Token) of {Queued1, First1} = case ?TOKEN_NAME(Token) of
yaml_anchor -> {Queued, First}; yaml_anchor -> {Queued, First};
_ -> {Queued - 1, First + 1} _ -> {Queued - 1, First + 1}
end, end,
Ready1 = case Not_Fun of
acc -> [Token | Ready];
drop -> Ready
end,
Parser#yaml_parser{ Parser#yaml_parser{
tks_queued = Queued1, tks_queued = Queued1,
tks_first_idx = First1, tks_first_idx = First1,
tks_emitted = Emitted + 1, tks_emitted = Emitted + 1,
last_token = Token, last_token = Token,
tks_ready = [Token | Ready] tks_ready = Ready1
}; };
do_emit_token( do_emit_token(
#yaml_parser{token_fun = Fun, #yaml_parser{token_fun = Fun,
@ -4115,6 +4119,10 @@ is_option_valid({doc_version, {Major, Minor}}) when
is_option_valid({io_blocksize, BS}) is_option_valid({io_blocksize, BS})
when is_integer(BS) andalso BS >= 1 -> when is_integer(BS) andalso BS >= 1 ->
true; true;
is_option_valid({token_fun, acc}) ->
true;
is_option_valid({token_fun, drop}) ->
true;
is_option_valid({token_fun, Fun}) is_option_valid({token_fun, Fun})
when is_function(Fun, 1) -> when is_function(Fun, 1) ->
true; true;
@ -4146,7 +4154,7 @@ invalid_option(Option) ->
Error#yaml_invalid_option{ Error#yaml_invalid_option{
text = "Invalid value for option \"token_fun\": " text = "Invalid value for option \"token_fun\": "
"it must be a function taking the parser state " "it must be a function taking the parser state "
"as its sole argument" "as its sole argument, or the atom 'acc' or 'drop'"
}; };
_ -> _ ->
yaml_errors:format(Error, "Unknown option \"~w\"", [Option]) yaml_errors:format(Error, "Unknown option \"~w\"", [Option])