Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Endleaf rejiggle, .fsm syntax for endids, refactor endid get/set api, various related bugfixes #479

Merged
merged 28 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
2afe563
Default to printing endids when no .endleaf callback is present.
katef Jun 7, 2024
ffea1de
Return a set of endids, rather than the state id.
katef Jun 7, 2024
f84aa38
Naming. I'm keeping "id" free.
katef Jun 8, 2024
a7d2e50
Add syntax for endids in .fsm format.
katef Jun 10, 2024
9ce1fb0
Missing error handling for the initial token.
katef Jun 10, 2024
0447463
Allow an empty list of end-ids.
katef Jun 11, 2024
1d30a12
Bugfix for argv handling for fsm_exec cli usage.
katef Jun 11, 2024
ebdbbbd
Tests for .fsm syntax.
katef Jun 11, 2024
db27a74
Wrong type.
katef Jun 11, 2024
26b9d25
Printing for endids.
katef Jun 11, 2024
20ac21b
Printing for endids.
katef Jun 11, 2024
8edcc07
Printing for endids.
katef Jun 11, 2024
69efe14
Missing free.
katef Jun 11, 2024
2b4821e
Printing for endids.
katef Jun 11, 2024
e07f66e
No need for the wrapper functions here.
katef Jun 11, 2024
ed4709c
No need for the tri-state enum here.
katef Jun 12, 2024
c27a1e4
Missing error handling.
katef Jun 12, 2024
d981fdd
No need for the tri-state enum here.
katef Jun 12, 2024
05b2467
No need for the static buffer here.
katef Jun 12, 2024
1c88c75
Statements after declarations for generated code.
katef Jun 14, 2024
0620f55
No need to mark unused here, this opaque pointer is passed to the get…
katef Jun 14, 2024
e577435
No need for the `void *opaque` arguments here.
katef Jun 14, 2024
6ec0aef
No need for the end_ids struct here.
katef Jun 14, 2024
1e5cf21
Normalization; attempting to get consistency around endleaf handling.
katef Jun 14, 2024
f7bcbdd
Remove dependencies on *nwritten, fsm_endid_count() beforehand instead.
katef Jun 15, 2024
6b2426d
No need for the *nwritten parameter.
katef Jun 15, 2024
99fa19c
Getting 0 end IDs is not an error.
katef Jun 15, 2024
f663cd4
Naming; ids[] for endids.
katef Jun 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ SUBDIR += tests/subtract
SUBDIR += tests/determinise
SUBDIR += tests/endids
SUBDIR += tests/epsilons
SUBDIR += tests/fsm
SUBDIR += tests/glob
SUBDIR += tests/like
SUBDIR += tests/literal
Expand Down
38 changes: 17 additions & 21 deletions include/fsm/fsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,6 @@ typedef unsigned int fsm_end_id_t;

#define FSM_END_ID_MAX UINT_MAX

/* struct used to return a collection of end IDs. */
struct fsm_end_ids {
unsigned count;
fsm_end_id_t ids[1];
};

/*
* Create a new FSM. This is to be freed with fsm_free(). A structure allocated
* from fsm_new() is expected to be passed as the "fsm" argument to the
Expand Down Expand Up @@ -222,29 +216,31 @@ fsm_setendid(struct fsm *fsm, fsm_end_id_t id);
* Returns 1 on success, 0 on error.
* */
int
fsm_setendidstate(struct fsm *fsm, fsm_state_t end_state, fsm_end_id_t id);
fsm_endid_set(struct fsm *fsm, fsm_state_t end_state, fsm_end_id_t id);

/* Get the end IDs associated with an end state, if any.
* If id_buf has enough cells to store all the end IDs (according
* to id_buf_count) then they are written into id_buf[] and
* *ids_written is set to the number of IDs. The end IDs in the
* buffer may appear in any order, but should not have duplicates.
* id_buf is expected to have enough cells (according to id_buf_count)
* to store all the end IDs. You can find this with fsm_endid_count().
*
* The end IDs in the buffer may appear in any order,
* but will not have duplicates.
*
* A state with no end IDs set is considered equivalent to a state
* that has the empty set, this API does not distinguish these cases.
* This is not an error.
*
* It is an error to attempt to get end IDs associated with a state
* that is not marked as an end state.
*
* Returns 0 if there is not enough space in id_buf for the
* end IDs, or 1 if zero or more end IDs were returned. */
enum fsm_getendids_res {
FSM_GETENDIDS_NOT_FOUND,
FSM_GETENDIDS_FOUND,
FSM_GETENDIDS_ERROR_INSUFFICIENT_SPACE = -1
};
enum fsm_getendids_res
fsm_getendids(const struct fsm *fsm, fsm_state_t end_state,
size_t id_buf_count, fsm_end_id_t *id_buf,
size_t *ids_written);
int
fsm_endid_get(const struct fsm *fsm, fsm_state_t end_state,
size_t id_buf_count, fsm_end_id_t *id_buf);
silentbicycle marked this conversation as resolved.
Show resolved Hide resolved

/* Get the number of end IDs associated with an end state. */
size_t
fsm_getendidcount(const struct fsm *fsm, fsm_state_t end_state);
fsm_endid_count(const struct fsm *fsm, fsm_state_t end_state);

/* Callback function to remap the end ids of a state. This function can
* remap to fewer end ids, but cannot add additional end ids, and cannot
Expand Down
7 changes: 5 additions & 2 deletions include/fsm/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,15 @@ struct fsm_options {
const char *cp;

/* TODO: explain. for C code fragment output */
int (*leaf)(FILE *, const struct fsm_end_ids *ids,
int (*leaf)(FILE *, const fsm_end_id_t *ids, size_t count,
const void *leaf_opaque);
void *leaf_opaque;

/* TODO: explain. for C code fragment output */
int (*endleaf)(FILE *, const struct fsm_end_ids *ids,
/* Placement in the output stream depends on the format.
* This replaces an entire "return xyz;" statement for C-like formats,
* but appends extra information for others. */
int (*endleaf)(FILE *, const fsm_end_id_t *ids, size_t count,
const void *endleaf_opaque);
void *endleaf_opaque;

Expand Down
25 changes: 17 additions & 8 deletions src/fsm/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -477,17 +477,14 @@ main(int argc, char *argv[])
struct fsm *q;

if ((op & OP_ARITY) == 1) {
if (argc > 1) {
usage();
exit(EXIT_FAILURE);
}
/* argc < 1 is okay */

q = fsm_parse((argc == 0) ? stdin : xopen(argv[0]), &opt);
if (q == NULL) {
exit(EXIT_FAILURE);
}
} else {
if (argc != 2) {
if (argc < 2) {
usage();
exit(EXIT_FAILURE);
}
Expand Down Expand Up @@ -610,6 +607,17 @@ main(int argc, char *argv[])
printf("=> total %g ms (avg %g ms)\n", elapsed, elapsed / iterations);
}

/* we're done consuming filenames, remaining argv is text to match */
if ((op & OP_ARITY) == 1) {
if (argc > 0) {
argc -= 1;
argv += 1;
}
} else {
argc -= 2;
argv += 2;
}

/* henceforth, r is $?-convention (0 for success) */

if (fsm == NULL) {
Expand Down Expand Up @@ -661,14 +669,15 @@ main(int argc, char *argv[])
}
}

/* TODO: optional -- to delimit texts as opposed to .fsm filenames */
if (op == OP_IDENTITY && argc > 0) {
/* match text */
if (argc > 0) {
int i;

/* TODO: option to print input texts which match. like grep(1) does.
* This is not the same as printing patterns which match (by associating
* a pattern to the end state), like lx(1) does */

/* TODO: optional -- to delimit texts as opposed to .fsm filenames */
for (i = 0; i < argc; i++) {
fsm_state_t state;
int e;
Expand All @@ -694,7 +703,7 @@ main(int argc, char *argv[])
continue;
}

/* TODO: option to print state number? */
/* TODO: option to print matching end-ids */
}
}

Expand Down
4 changes: 1 addition & 3 deletions src/libfsm/clone.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,13 @@ static int
copy_end_ids_cb(fsm_state_t state, const fsm_end_id_t id, void *opaque)
{
struct copy_end_ids_env *env = opaque;
enum fsm_endid_set_res sres;
assert(env->tag == 'c');

#if LOG_CLONE_ENDIDS
fprintf(stderr, "clone[%d] <- %d\n", state, id);
#endif

sres = fsm_endid_set(env->dst, state, id);
if (sres == FSM_ENDID_SET_ERROR_ALLOC_FAIL) {
if (!fsm_endid_set(env->dst, state, id)) {
env->ok = 0;
return 0;
}
Expand Down
9 changes: 2 additions & 7 deletions src/libfsm/consolidate.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,19 +231,14 @@ static int
consolidate_end_ids_cb(fsm_state_t state, const fsm_end_id_t *ids, size_t num_ids, void *opaque)
{
struct consolidate_end_ids_env *env = opaque;
enum fsm_endid_set_res sres;
fsm_state_t s;
assert(env->tag == 'C');

assert(state < env->mapping_count);
s = env->mapping[state];

sres = fsm_endid_set_bulk(env->dst, s, num_ids, ids, FSM_ENDID_BULK_APPEND);
if (sres == FSM_ENDID_SET_ERROR_ALLOC_FAIL) {
return 0;
}

return 1;
return fsm_endid_set_bulk(env->dst, s,
num_ids, ids, FSM_ENDID_BULK_APPEND);
}

static int
Expand Down
Loading
Loading