Add p_value_get() / p_value_get_XXX() accessors
Allow user code to access specific pvalue values, especially when multiple ptypes are in use.
This commit is contained in:
parent
b641c64425
commit
5ac3ad1655
@ -94,6 +94,14 @@ public <%= @grammar.prefix %>value_t <%= @grammar.prefix %>value<%= name == "def
|
|||||||
return <%= @grammar.prefix %>value_t(v_<%= name %>: v);
|
return <%= @grammar.prefix %>value_t(v_<%= name %>: v);
|
||||||
}
|
}
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
/** Parser value accessor(s). */
|
||||||
|
<% @grammar.ptypes.each do |name, typestring| %>
|
||||||
|
public <%= typestring %> <%= @grammar.prefix %>value_get<%= name == "default" ? "" : "_#{name}" %>(<%= @grammar.prefix %>value_t * pvalue)
|
||||||
|
{
|
||||||
|
return pvalue.v_<%= name %>;
|
||||||
|
}
|
||||||
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<% if @grammar.tree %>
|
<% if @grammar.tree %>
|
||||||
|
|||||||
@ -77,6 +77,14 @@ static inline <%= @grammar.prefix %>value_t <%= @grammar.prefix %>value<%= name
|
|||||||
return (<%= @grammar.prefix %>value_t){.v_<%= name %> = v};
|
return (<%= @grammar.prefix %>value_t){.v_<%= name %> = v};
|
||||||
}
|
}
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
/** Parser value accessor(s). */
|
||||||
|
<% @grammar.ptypes.each do |name, typestring| %>
|
||||||
|
static inline <%= typestring %> <%= @grammar.prefix %>value_get<%= name == "default" ? "" : "_#{name}" %>(<%= @grammar.prefix %>value_t const * pvalue)
|
||||||
|
{
|
||||||
|
return pvalue->v_<%= name %>;
|
||||||
|
}
|
||||||
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<% if @grammar.tree %>
|
<% if @grammar.tree %>
|
||||||
|
|||||||
@ -1082,6 +1082,9 @@ The `p_token_info_t` structure contains the following fields:
|
|||||||
* `length` (`size_t`) holds the number of input bytes used by the token.
|
* `length` (`size_t`) holds the number of input bytes used by the token.
|
||||||
* `token` (`p_token_t`) holds the token ID of the lexed token
|
* `token` (`p_token_t`) holds the token ID of the lexed token
|
||||||
* `pvalue` (`p_value_t`) holds the parser value associated with the token.
|
* `pvalue` (`p_value_t`) holds the parser value associated with the token.
|
||||||
|
The actual user value can be extracted with `p_value_get(&token_info.pvalue)`
|
||||||
|
for the default value or `p_value_get_XXX(&token_info.pvalue)` for named
|
||||||
|
`ptype` values.
|
||||||
|
|
||||||
### Tree Node Types
|
### Tree Node Types
|
||||||
|
|
||||||
@ -1404,18 +1407,35 @@ In this case, Propane will free a `Statement` tree structure returned by the
|
|||||||
|
|
||||||
### `p_value`
|
### `p_value`
|
||||||
|
|
||||||
When tree generation mode is not active, the `p_value_t` union can hold one of
|
The `p_value(v)` function builds an instance of the `p_value_t` with the
|
||||||
several different possible value types.
|
|
||||||
|
|
||||||
The `p_value(v)` function returns an instance of the `p_value_t` with the
|
|
||||||
default member set to the value of `v`.
|
default member set to the value of `v`.
|
||||||
|
|
||||||
A `p_value_XXX(v)` function is set for each user-defined `ptype` name with
|
A `p_value_XXX(v)` function is defined for each user-defined `ptype` name with
|
||||||
the user-given name in place of the `XXX`.
|
the user-given name in place of the `XXX`.
|
||||||
|
|
||||||
These functions are useful for custom lexer functions which need to return a
|
These functions are useful for custom lexer functions which need to return a
|
||||||
parser value corresponding to a lexed token.
|
parser value corresponding to a lexed token.
|
||||||
|
|
||||||
|
They are especially useful when tree generation mode is not active.
|
||||||
|
In that case, the `p_value_t` union can hold one of several different possible
|
||||||
|
value types.
|
||||||
|
|
||||||
|
### `p_value_get`
|
||||||
|
|
||||||
|
The `p_value_get()` accessor functions can be used to extract a user value
|
||||||
|
from a `p_value_t` union.
|
||||||
|
|
||||||
|
The `p_value_get(pvalue)` function accepts a pointer to a `p_value_t` and
|
||||||
|
returns the value of its default member.
|
||||||
|
|
||||||
|
A `p_value_get_XXX(pvalue)` function is generated for each user-defined `ptype`
|
||||||
|
name with the user-given name in place of the `XXX`, returning the value of the
|
||||||
|
corresponding member.
|
||||||
|
|
||||||
|
These functions are the counterpart to `p_value()` constructor functions and
|
||||||
|
are useful for reading the parser value associated with a lexed token, for
|
||||||
|
example `p_value_get(&token_info.pvalue)`.
|
||||||
|
|
||||||
##> Data
|
##> Data
|
||||||
|
|
||||||
### `p_token_names`
|
### `p_token_names`
|
||||||
|
|||||||
@ -1781,6 +1781,39 @@ EOF
|
|||||||
results = run_test(language: language)
|
results = run_test(language: language)
|
||||||
expect(results.status).to eq 0
|
expect(results.status).to eq 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "provides accessor functions to extract user values from a parser value" do
|
||||||
|
if language == "d"
|
||||||
|
write_grammar <<EOF
|
||||||
|
ptype int;
|
||||||
|
ptype float = float;
|
||||||
|
ptype string = string;
|
||||||
|
|
||||||
|
drop /\\s+/;
|
||||||
|
token num /\\d+/ << $$ = 42; >>
|
||||||
|
token flt (float) /f/ << $$ = 1.5; >>
|
||||||
|
token str (string) /s/ << $$ = "hello"; >>
|
||||||
|
Start -> num flt str;
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
write_grammar <<EOF
|
||||||
|
ptype int;
|
||||||
|
ptype float = float;
|
||||||
|
ptype string = char *;
|
||||||
|
|
||||||
|
drop /\\s+/;
|
||||||
|
token num /\\d+/ << $$ = 42; >>
|
||||||
|
token flt (float) /f/ << $$ = 1.5; >>
|
||||||
|
token str (string) /s/ << $$ = (char *)"hello"; >>
|
||||||
|
Start -> num flt str;
|
||||||
|
EOF
|
||||||
|
end
|
||||||
|
run_propane(language: language)
|
||||||
|
compile("spec/test_value_accessors.#{language}", language: language)
|
||||||
|
results = run_test(language: language)
|
||||||
|
expect(results.stderr).to eq ""
|
||||||
|
expect(results.status).to eq 0
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
29
spec/test_value_accessors.c
Normal file
29
spec/test_value_accessors.c
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include "testparser.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
p_token_info_t token_info;
|
||||||
|
char const * input = "42 f s";
|
||||||
|
p_context_t * context;
|
||||||
|
context = p_context_new((uint8_t const *)input, strlen(input));
|
||||||
|
|
||||||
|
/* Default ptype value extracted with p_value_get(). */
|
||||||
|
assert(p_lex(context, &token_info) == P_SUCCESS);
|
||||||
|
assert(token_info.token == TOKEN_num);
|
||||||
|
assert(p_value_get(&token_info.pvalue) == 42);
|
||||||
|
|
||||||
|
/* Named ptype values extracted with p_value_get_XXX(). */
|
||||||
|
assert(p_lex(context, &token_info) == P_SUCCESS);
|
||||||
|
assert(token_info.token == TOKEN_flt);
|
||||||
|
assert(p_value_get_float(&token_info.pvalue) == 1.5);
|
||||||
|
|
||||||
|
assert(p_lex(context, &token_info) == P_SUCCESS);
|
||||||
|
assert(token_info.token == TOKEN_str);
|
||||||
|
assert(strcmp(p_value_get_string(&token_info.pvalue), "hello") == 0);
|
||||||
|
|
||||||
|
p_context_delete(context);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
29
spec/test_value_accessors.d
Normal file
29
spec/test_value_accessors.d
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import testparser;
|
||||||
|
import std.stdio;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
p_token_info_t token_info;
|
||||||
|
string input = "42 f s";
|
||||||
|
p_context_t * context;
|
||||||
|
context = p_context_new(input);
|
||||||
|
|
||||||
|
/* Default ptype value extracted with p_value_get(). */
|
||||||
|
assert(p_lex(context, &token_info) == P_SUCCESS);
|
||||||
|
assert(token_info.token == TOKEN_num);
|
||||||
|
assert(p_value_get(&token_info.pvalue) == 42);
|
||||||
|
|
||||||
|
/* Named ptype values extracted with p_value_get_XXX(). */
|
||||||
|
assert(p_lex(context, &token_info) == P_SUCCESS);
|
||||||
|
assert(token_info.token == TOKEN_flt);
|
||||||
|
assert(p_value_get_float(&token_info.pvalue) == 1.5);
|
||||||
|
|
||||||
|
assert(p_lex(context, &token_info) == P_SUCCESS);
|
||||||
|
assert(token_info.token == TOKEN_str);
|
||||||
|
assert(p_value_get_string(&token_info.pvalue) == "hello");
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user