wip
This commit is contained in:
parent
35acdde09f
commit
9760da4df4
@ -310,7 +310,22 @@ EOF
|
||||
end
|
||||
|
||||
it "executes user code when matching lexer token" do
|
||||
write_grammar <<EOF
|
||||
case language
|
||||
when "c"
|
||||
write_grammar <<EOF
|
||||
<<
|
||||
#include <stdio.h>
|
||||
>>
|
||||
token abc <<
|
||||
printf("abc!\\n");
|
||||
>>
|
||||
token def;
|
||||
Start -> Abcs def;
|
||||
Abcs -> ;
|
||||
Abcs -> abc Abcs;
|
||||
EOF
|
||||
when "d"
|
||||
write_grammar <<EOF
|
||||
<<
|
||||
import std.stdio;
|
||||
>>
|
||||
@ -322,6 +337,7 @@ Start -> Abcs def;
|
||||
Abcs -> ;
|
||||
Abcs -> abc Abcs;
|
||||
EOF
|
||||
end
|
||||
build_parser(language: language)
|
||||
compile("spec/test_user_code.#{language}", language: language)
|
||||
results = run
|
||||
@ -336,7 +352,20 @@ EOF
|
||||
end
|
||||
|
||||
it "supports a pattern statement" do
|
||||
write_grammar <<EOF
|
||||
case language
|
||||
when "c"
|
||||
write_grammar <<EOF
|
||||
<<
|
||||
#include <stdio.h>
|
||||
>>
|
||||
token abc;
|
||||
/def/ <<
|
||||
printf("def!\\n");
|
||||
>>
|
||||
Start -> abc;
|
||||
EOF
|
||||
when "d"
|
||||
write_grammar <<EOF
|
||||
<<
|
||||
import std.stdio;
|
||||
>>
|
||||
@ -346,6 +375,7 @@ token abc;
|
||||
>>
|
||||
Start -> abc;
|
||||
EOF
|
||||
end
|
||||
build_parser(language: language)
|
||||
compile("spec/test_pattern.#{language}", language: language)
|
||||
results = run
|
||||
@ -360,7 +390,24 @@ EOF
|
||||
end
|
||||
|
||||
it "supports returning tokens from pattern code blocks" do
|
||||
write_grammar <<EOF
|
||||
case language
|
||||
when "c"
|
||||
write_grammar <<EOF
|
||||
<<
|
||||
#include <stdio.h>
|
||||
>>
|
||||
token abc;
|
||||
/def/ <<
|
||||
printf("def!\\n");
|
||||
>>
|
||||
/ghi/ <<
|
||||
printf("ghi!\\n");
|
||||
return $token(abc);
|
||||
>>
|
||||
Start -> abc;
|
||||
EOF
|
||||
when "d"
|
||||
write_grammar <<EOF
|
||||
<<
|
||||
import std.stdio;
|
||||
>>
|
||||
@ -374,6 +421,7 @@ token abc;
|
||||
>>
|
||||
Start -> abc;
|
||||
EOF
|
||||
end
|
||||
build_parser(language: language)
|
||||
compile("spec/test_return_token_from_pattern.#{language}", language: language)
|
||||
results = run
|
||||
@ -386,7 +434,31 @@ EOF
|
||||
end
|
||||
|
||||
it "supports lexer modes" do
|
||||
write_grammar <<EOF
|
||||
case language
|
||||
when "c"
|
||||
write_grammar <<EOF
|
||||
<<
|
||||
#include <stdio.h>
|
||||
>>
|
||||
token abc;
|
||||
token def;
|
||||
tokenid string;
|
||||
drop /\\s+/;
|
||||
/"/ <<
|
||||
printf("begin string mode\\n");
|
||||
$mode(string);
|
||||
>>
|
||||
string: /[^"]+/ <<
|
||||
printf("captured string\\n");
|
||||
>>
|
||||
string: /"/ <<
|
||||
$mode(default);
|
||||
return $token(string);
|
||||
>>
|
||||
Start -> abc string def;
|
||||
EOF
|
||||
when "d"
|
||||
write_grammar <<EOF
|
||||
<<
|
||||
import std.stdio;
|
||||
>>
|
||||
@ -407,6 +479,7 @@ string: /"/ <<
|
||||
>>
|
||||
Start -> abc string def;
|
||||
EOF
|
||||
end
|
||||
build_parser(language: language)
|
||||
compile("spec/test_lexer_modes.#{language}", language: language)
|
||||
results = run
|
||||
@ -422,7 +495,26 @@ EOF
|
||||
end
|
||||
|
||||
it "executes user code associated with a parser rule" do
|
||||
write_grammar <<EOF
|
||||
case language
|
||||
when "c"
|
||||
write_grammar <<EOF
|
||||
<<
|
||||
#include <stdio.h>
|
||||
>>
|
||||
token a;
|
||||
token b;
|
||||
Start -> A B <<
|
||||
printf("Start!\\n");
|
||||
>>
|
||||
A -> a <<
|
||||
printf("A!\\n");
|
||||
>>
|
||||
B -> b <<
|
||||
printf("B!\\n");
|
||||
>>
|
||||
EOF
|
||||
when "d"
|
||||
write_grammar <<EOF
|
||||
<<
|
||||
import std.stdio;
|
||||
>>
|
||||
@ -438,6 +530,7 @@ B -> b <<
|
||||
writeln("B!");
|
||||
>>
|
||||
EOF
|
||||
end
|
||||
build_parser(language: language)
|
||||
compile("spec/test_parser_rule_user_code.#{language}", language: language)
|
||||
results = run
|
||||
@ -451,7 +544,7 @@ EOF
|
||||
|
||||
it "parses lists" do
|
||||
write_grammar <<EOF
|
||||
ptype uint;
|
||||
ptype #{language == "c" ? "uint32_t" : "uint"};
|
||||
token a;
|
||||
Start -> As <<
|
||||
$$ = $1;
|
||||
@ -490,7 +583,23 @@ EOF
|
||||
end
|
||||
|
||||
it "provides matched text to user code blocks" do
|
||||
write_grammar <<EOF
|
||||
case language
|
||||
when "c"
|
||||
write_grammar <<EOF
|
||||
<<
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
>>
|
||||
token id /[a-zA-Z_][a-zA-Z0-9_]*/ <<
|
||||
char * t = malloc(match_length + 1);
|
||||
strncpy(t, (char *)match, match_length);
|
||||
printf("Matched token is %s\\n", t);
|
||||
free(t);
|
||||
>>
|
||||
Start -> id;
|
||||
EOF
|
||||
when "d"
|
||||
write_grammar <<EOF
|
||||
<<
|
||||
import std.stdio;
|
||||
>>
|
||||
@ -499,6 +608,7 @@ token id /[a-zA-Z_][a-zA-Z0-9_]*/ <<
|
||||
>>
|
||||
Start -> id;
|
||||
EOF
|
||||
end
|
||||
build_parser(language: language)
|
||||
compile("spec/test_lexer_match_text.#{language}", language: language)
|
||||
results = run
|
||||
@ -510,7 +620,19 @@ EOF
|
||||
end
|
||||
|
||||
it "allows storing a result value for the lexer" do
|
||||
write_grammar <<EOF
|
||||
case language
|
||||
when "c"
|
||||
write_grammar <<EOF
|
||||
ptype uint64_t;
|
||||
token word /[a-z]+/ <<
|
||||
$$ = match_length;
|
||||
>>
|
||||
Start -> word <<
|
||||
$$ = $1;
|
||||
>>
|
||||
EOF
|
||||
when "d"
|
||||
write_grammar <<EOF
|
||||
ptype ulong;
|
||||
token word /[a-z]+/ <<
|
||||
$$ = match.length;
|
||||
@ -519,6 +641,7 @@ Start -> word <<
|
||||
$$ = $1;
|
||||
>>
|
||||
EOF
|
||||
end
|
||||
build_parser(language: language)
|
||||
compile("spec/test_lexer_result_value.#{language}", language: language)
|
||||
results = run
|
||||
|
39
spec/test_error_positions.c
Normal file
39
spec/test_error_positions.c
Normal file
@ -0,0 +1,39 @@
|
||||
#include "testparser.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char const * input = "a 42";
|
||||
p_context_t context;
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_SUCCESS);
|
||||
|
||||
input = "a\n123\na a";
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_UNEXPECTED_TOKEN);
|
||||
assert(p_position(&context).row == 2);
|
||||
assert(p_position(&context).col == 3);
|
||||
assert(context.token == TOKEN_a);
|
||||
|
||||
input = "12";
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_UNEXPECTED_TOKEN);
|
||||
assert(p_position(&context).row == 0);
|
||||
assert(p_position(&context).col == 0);
|
||||
assert(context.token == TOKEN_num);
|
||||
|
||||
input = "a 12\n\nab";
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_UNEXPECTED_INPUT);
|
||||
assert(p_position(&context).row == 2);
|
||||
assert(p_position(&context).col == 1);
|
||||
|
||||
input = "a 12\n\na\n\n77\na \xAA";
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_DECODE_ERROR);
|
||||
assert(p_position(&context).row == 5);
|
||||
assert(p_position(&context).col == 4);
|
||||
|
||||
return 0;
|
||||
}
|
@ -33,6 +33,5 @@ unittest
|
||||
input = "a 12\n\na\n\n77\na \xAA";
|
||||
p_context_init(&context, input);
|
||||
assert(p_parse(&context) == P_DECODE_ERROR);
|
||||
writeln(p_position(&context));
|
||||
assert(p_position(&context) == p_position_t(5, 4));
|
||||
}
|
||||
|
15
spec/test_lexer_match_text.c
Normal file
15
spec/test_lexer_match_text.c
Normal file
@ -0,0 +1,15 @@
|
||||
#include "testparser.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char const * input = "identifier_123";
|
||||
p_context_t context;
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_SUCCESS);
|
||||
printf("pass1\n");
|
||||
|
||||
return 0;
|
||||
}
|
20
spec/test_lexer_modes.c
Normal file
20
spec/test_lexer_modes.c
Normal file
@ -0,0 +1,20 @@
|
||||
#include "testparser.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char const * input = "abc \"a string\" def";
|
||||
p_context_t context;
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_SUCCESS);
|
||||
printf("pass1\n");
|
||||
|
||||
input = "abc \"abc def\" def";
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_SUCCESS);
|
||||
printf("pass2\n");
|
||||
|
||||
return 0;
|
||||
}
|
19
spec/test_lexer_result_value.c
Normal file
19
spec/test_lexer_result_value.c
Normal file
@ -0,0 +1,19 @@
|
||||
#include "testparser.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char const * input = "x";
|
||||
p_context_t context;
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_SUCCESS);
|
||||
assert(p_result(&context) == 1u);
|
||||
|
||||
input = "fabulous";
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_SUCCESS);
|
||||
assert(p_result(&context) == 8u);
|
||||
|
||||
return 0;
|
||||
}
|
17
spec/test_parser_identical_rules_lookahead.c
Normal file
17
spec/test_parser_identical_rules_lookahead.c
Normal file
@ -0,0 +1,17 @@
|
||||
#include "testparser.h"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char const * input = "aba";
|
||||
p_context_t context;
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_SUCCESS);
|
||||
|
||||
input = "abb";
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_SUCCESS);
|
||||
|
||||
return 0;
|
||||
}
|
24
spec/test_parser_rule_from_multiple_states.c
Normal file
24
spec/test_parser_rule_from_multiple_states.c
Normal file
@ -0,0 +1,24 @@
|
||||
#include "testparser.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char const * input = "a";
|
||||
p_context_t context;
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_UNEXPECTED_TOKEN);
|
||||
assert(p_position(&context).row == 0);
|
||||
assert(p_position(&context).col == 1);
|
||||
assert(context.token == TOKEN___EOF);
|
||||
|
||||
input = "a b";
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_SUCCESS);
|
||||
|
||||
input = "bb";
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_SUCCESS);
|
||||
|
||||
return 0;
|
||||
}
|
13
spec/test_parser_rule_user_code.c
Normal file
13
spec/test_parser_rule_user_code.c
Normal file
@ -0,0 +1,13 @@
|
||||
#include "testparser.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char const * input = "ab";
|
||||
p_context_t context;
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_SUCCESS);
|
||||
|
||||
return 0;
|
||||
}
|
24
spec/test_parsing_lists.c
Normal file
24
spec/test_parsing_lists.c
Normal file
@ -0,0 +1,24 @@
|
||||
#include "testparser.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char const * input = "a";
|
||||
p_context_t context;
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_SUCCESS);
|
||||
assert(p_result(&context) == 1u);
|
||||
|
||||
input = "";
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_SUCCESS);
|
||||
assert(p_result(&context) == 0u);
|
||||
|
||||
input = "aaaaaaaaaaaaaaaa";
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_SUCCESS);
|
||||
assert(p_result(&context) == 16u);
|
||||
|
||||
return 0;
|
||||
}
|
20
spec/test_pattern.c
Normal file
20
spec/test_pattern.c
Normal file
@ -0,0 +1,20 @@
|
||||
#include "testparser.h"
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char const * input = "abcdef";
|
||||
p_context_t context;
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_SUCCESS);
|
||||
printf("pass1\n");
|
||||
|
||||
input = "defabcdef";
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_SUCCESS);
|
||||
printf("pass2\n");
|
||||
|
||||
return 0;
|
||||
}
|
13
spec/test_return_token_from_pattern.c
Normal file
13
spec/test_return_token_from_pattern.c
Normal file
@ -0,0 +1,13 @@
|
||||
#include "testparser.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char const * input = "defghidef";
|
||||
p_context_t context;
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_SUCCESS);
|
||||
|
||||
return 0;
|
||||
}
|
20
spec/test_user_code.c
Normal file
20
spec/test_user_code.c
Normal file
@ -0,0 +1,20 @@
|
||||
#include "testparser.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char const * input = "abcdef";
|
||||
p_context_t context;
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_SUCCESS);
|
||||
printf("pass1\n");
|
||||
|
||||
input = "abcabcdef";
|
||||
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||
assert(p_parse(&context) == P_SUCCESS);
|
||||
printf("pass2\n");
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user