Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/bel-framework/bel-scan
Generic scanner for Erlang
https://github.com/bel-framework/bel-scan
erlang erlang-library parser parser-library
Last synced: about 1 month ago
JSON representation
Generic scanner for Erlang
- Host: GitHub
- URL: https://github.com/bel-framework/bel-scan
- Owner: bel-framework
- License: apache-2.0
- Created: 2024-04-15T10:57:56.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2024-04-30T20:32:10.000Z (7 months ago)
- Last Synced: 2024-09-30T03:41:47.268Z (about 2 months ago)
- Topics: erlang, erlang-library, parser, parser-library
- Language: Erlang
- Homepage:
- Size: 92.8 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE.md
Awesome Lists containing this project
README
# bel-framework/bel-scan
Generic scanner for Erlang.
## Example
The example below is simplistic and scans a string into a tokens list containing params and texts. Params are enclosed with two brackets, like `{{ foo }}`, and produces the token `{param, {Line, Column}, <<"foo">>}`. Texts, like `bar`, are scanned as `{text, {Line, Column}, <<"bar">>}`.
The output of the [module](#module) of the example below is:
```shell
1> my_scan:string(<<"foo {{ bar }} baz">>).
[{text,{1,1},<<"foo ">>},
{param,{1,5},<<"bar">>},
{text,{1,14},<<" baz">>}]
```### Module
```erlang
-module(my_scan).
-behaviour(bel_scan).% API
-export([ string/1 ]).% bel_scan callbacks
-export([ init/1, handle_char/3, handle_tokens/2 ]).-import(bel_scan, [ incr_col/1
, incr_col/2
, new_ln/1
, continue/2
, skip_new_lns/2
, update_pos/1
, token/2
, push_token/2
, snapshot/1
, fold/2
]).-record(state, {}).
%%%=====================================================================
%%% API
%%%=====================================================================string(Text) ->
Scan = bel_scan:new(#{
input => Text,
handler => ?MODULE
}),
bel_scan:string(#{}, Scan).%%%=====================================================================
%%% bel_scan callbacks
%%%=====================================================================init(Opts) when is_map(Opts) ->
{ok, #state{}}.handle_char(${, <<${, $\s, Rest/bitstring>>, Scan) ->
scan_param(Rest, fold(Scan, [
fun(S) -> push_token(token(text, S), S) end,
fun(S) -> snapshot(S) end,
fun(S) -> incr_col(3, S) end,
fun(S) -> update_pos(S) end
]));
handle_char(_Char, <<>>, Scan) ->
continue(<<>>, fold(Scan, [
fun(S) -> incr_col(S) end,
fun(S) -> push_token(token(text, S), S) end
]));
handle_char(_Char, <>, Scan) ->
continue(Rest, incr_col(Scan)).handle_tokens(Tokens, _Scan) ->
lists:reverse(Tokens).%%%=====================================================================
%%% Internal functions
%%%=====================================================================scan_param(<<$\s, $}, $}, Rest/bitstring>>, Scan) ->
continue(Rest, fold(Scan, [
fun(S) -> push_token(token(param, S), S) end,
fun(S) -> incr_col(3, S) end,
fun(S) -> update_pos(S) end,
fun(S) -> snapshot(S) end
]));
scan_param(<>, Scan0) ->
{ok, {_Char, Rest, Scan}} = skip_new_lns(Rest0, Scan0),
scan_param(Rest, incr_col(Scan)).
```## Build
```shell
$ rebar3 compile
```## Test
```shell
$ rebar3 eunit
```