arithy / packcc

A parser generator for C
Other
347 stars 28 forks source link

%value and memory management #66

Closed antoshre closed 6 months ago

antoshre commented 2 years ago

I'm trying to parse some input into a struct but I don't understand how to use %value to get a pointer in and out of the parser. A very stripped-down example of what I'd like to do:

//thing.h
enum STATE {
    FOO,
    BAR,
    BAZ
};
typedef struct {
    enum STATE state;
} cmds_t;
//the grammar
%header {
    #include "thing.h"
}

%value "cmds_t*"

COMMAND <- FOOBARBAZ
FOOBARBAZ <-
    "foo" { $$->state = FOO; } /
    "bar" { $$->state = BAR; } /
    "baz" { $$->state = BAZ; }
//main.c fragment
cmds_t* commands;
pcc_context_t* ctx = pcc_create(NULL);
int ret = pcc_parse(ctx, &commands);
//use *commands
//free(*commands) maybe?
pcc_destroy(ctx);

but obviously no memory is allocated so the FOOBARBAZ actions are null pointer derefs. Even if I pre-allocate memory or insert a dummy rule before FOOBARBAZ that allocates some memory that pointer only lives for the lifetime of the action and then leaks. I don't see a way to propagate a single pointer throughout rules without using methods that make all the subsequent rules significantly more complex. The simplicity of the actions is a huge positive for me.

I see in the TinyC example that a second data structure is passed around in auxil that looks like it holds the AST. Is this the intended approach for all applications? I certainly could use %auxil cmds_t* and then have all my actions use auxil->... but I feel like I'm missing something simple that would allow the above.

arithy commented 2 years ago

I see in the TinyC example that a second data structure is passed around in auxil that looks like it holds the AST. Is this the intended approach for all applications?

Yes, it is. In the Tiny-C example, I introduce the manager, which is passed via auxil, to hold all AST nodes so that the application can surely deallocate all memory used by AST nodes even if there are nodes that have no parent. If you ensure that all nodes have parents by designing the PEG finely, you can deallocate all memory by tree traversal from the root node.

PackCC doesn't care memory allocation or deallocation of application-defined data. Applications should have responsibility to manage them. However, If you have any idea of a concrete specification of the functionality to simplify the management, I'll consider to introduce it.

arithy commented 6 months ago

@antoshre , do you have any ideas? If you don't, let me close this issue for now. Feel free to reopen this when you come up with an idea.