Add p_input_index()
This commit is contained in:
1 parent
c0016f6d58
commit
2ebdeaa995
8 files changed
+173
No files matched your search
@@ -951,6 +951,21 @@ EOF
|
||||
expect(results.status).to eq 0
|
||||
end
|
||||
|
||||
it "exposes the current input byte offset via p_input_index()" do
|
||||
write_grammar <<EOF
|
||||
drop /\\s+/;
|
||||
token a;
|
||||
token b;
|
||||
start Start;
|
||||
Start -> a b;
|
||||
EOF
|
||||
run_propane(language: language)
|
||||
compile("spec/test_input_index.#{language}", language: language)
|
||||
results = run_test(language: language)
|
||||
expect(results.stderr).to eq ""
|
||||
expect(results.status).to eq 0
|
||||
end
|
||||
|
||||
it "allows creating a JSON parser" do
|
||||
ext = language == "cpp" ? "c" : language
|
||||
write_grammar(File.read("spec/json_parser.#{ext}.propane"))
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
#include "testparser.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "testutils.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
/* Grammar (simple):
|
||||
* drop /\\s+/;
|
||||
* token a; token b;
|
||||
* Start -> a b;
|
||||
*
|
||||
* Verifies that p_input_index() reports the parser/lexer's current byte
|
||||
* offset into the input text. */
|
||||
|
||||
/* Fresh context: input_index starts at 0. */
|
||||
{
|
||||
char const * input = "ab";
|
||||
p_context_t * context = p_context_new((uint8_t const *)input, strlen(input));
|
||||
assert_eq(0u, p_input_index(context));
|
||||
p_context_delete(context);
|
||||
}
|
||||
|
||||
/* After each successful lex the byte offset advances past the token. */
|
||||
{
|
||||
char const * input = "a b";
|
||||
p_context_t * context = p_context_new((uint8_t const *)input, strlen(input));
|
||||
p_token_info_t token_info;
|
||||
assert(p_lex(context, &token_info) == P_SUCCESS);
|
||||
assert_eq((size_t)TOKEN_a, (size_t)token_info.token);
|
||||
assert_eq(1u, p_input_index(context));
|
||||
assert(p_lex(context, &token_info) == P_SUCCESS);
|
||||
assert_eq((size_t)TOKEN_b, (size_t)token_info.token);
|
||||
/* The dropped space between `a` and `b` advances input_index too. */
|
||||
assert_eq(3u, p_input_index(context));
|
||||
p_context_delete(context);
|
||||
}
|
||||
|
||||
/* After a full successful parse, input_index has reached the end. */
|
||||
{
|
||||
char const * input = "ab";
|
||||
p_context_t * context = p_context_new((uint8_t const *)input, strlen(input));
|
||||
assert(p_parse_Start(context) == P_SUCCESS);
|
||||
assert_eq(2u, p_input_index(context));
|
||||
p_context_delete(context);
|
||||
}
|
||||
|
||||
/* When parse_inner completes via a follow token, the follow token is not
|
||||
* consumed, so input_index points at the start of the follow token. */
|
||||
{
|
||||
char const * input = "abb";
|
||||
p_context_t * context = p_context_new((uint8_t const *)input, strlen(input));
|
||||
p_token_t follow_tokens[] = { TOKEN_b };
|
||||
assert(p_parse_inner_Start(context, follow_tokens, 1u) == P_SUCCESS);
|
||||
assert_eq(2u, p_input_index(context));
|
||||
p_context_delete(context);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import testparser;
|
||||
import std.stdio;
|
||||
import testutils;
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
/* See test_input_index.c for details on the grammar and cases. */
|
||||
|
||||
/* Fresh context: input_index starts at 0. */
|
||||
{
|
||||
string input = "ab";
|
||||
p_context_t * context = p_context_new(input);
|
||||
assert(p_input_index(context) == 0);
|
||||
}
|
||||
|
||||
/* After each successful lex the byte offset advances past the token. */
|
||||
{
|
||||
string input = "a b";
|
||||
p_context_t * context = p_context_new(input);
|
||||
p_token_info_t token_info;
|
||||
assert(p_lex(context, &token_info) == P_SUCCESS);
|
||||
assert(token_info.token == TOKEN_a);
|
||||
assert(p_input_index(context) == 1);
|
||||
assert(p_lex(context, &token_info) == P_SUCCESS);
|
||||
assert(token_info.token == TOKEN_b);
|
||||
assert(p_input_index(context) == 3);
|
||||
}
|
||||
|
||||
/* After a full successful parse, input_index has reached the end. */
|
||||
{
|
||||
string input = "ab";
|
||||
p_context_t * context = p_context_new(input);
|
||||
assert(p_parse_Start(context) == P_SUCCESS);
|
||||
assert(p_input_index(context) == 2);
|
||||
}
|
||||
|
||||
/* When parse_inner completes via a follow token, the follow token is not
|
||||
* consumed, so input_index points at the start of the follow token. */
|
||||
{
|
||||
string input = "abb";
|
||||
p_context_t * context = p_context_new(input);
|
||||
p_token_t[] follow_tokens = [TOKEN_b];
|
||||
assert(p_parse_inner_Start(context, follow_tokens) == P_SUCCESS);
|
||||
assert(p_input_index(context) == 2);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user