wip
This commit is contained in:
parent
35acdde09f
commit
9760da4df4
@ -310,7 +310,22 @@ EOF
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "executes user code when matching lexer token" do
|
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;
|
import std.stdio;
|
||||||
>>
|
>>
|
||||||
@ -322,6 +337,7 @@ Start -> Abcs def;
|
|||||||
Abcs -> ;
|
Abcs -> ;
|
||||||
Abcs -> abc Abcs;
|
Abcs -> abc Abcs;
|
||||||
EOF
|
EOF
|
||||||
|
end
|
||||||
build_parser(language: language)
|
build_parser(language: language)
|
||||||
compile("spec/test_user_code.#{language}", language: language)
|
compile("spec/test_user_code.#{language}", language: language)
|
||||||
results = run
|
results = run
|
||||||
@ -336,7 +352,20 @@ EOF
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "supports a pattern statement" do
|
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;
|
import std.stdio;
|
||||||
>>
|
>>
|
||||||
@ -346,6 +375,7 @@ token abc;
|
|||||||
>>
|
>>
|
||||||
Start -> abc;
|
Start -> abc;
|
||||||
EOF
|
EOF
|
||||||
|
end
|
||||||
build_parser(language: language)
|
build_parser(language: language)
|
||||||
compile("spec/test_pattern.#{language}", language: language)
|
compile("spec/test_pattern.#{language}", language: language)
|
||||||
results = run
|
results = run
|
||||||
@ -360,7 +390,24 @@ EOF
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "supports returning tokens from pattern code blocks" do
|
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;
|
import std.stdio;
|
||||||
>>
|
>>
|
||||||
@ -374,6 +421,7 @@ token abc;
|
|||||||
>>
|
>>
|
||||||
Start -> abc;
|
Start -> abc;
|
||||||
EOF
|
EOF
|
||||||
|
end
|
||||||
build_parser(language: language)
|
build_parser(language: language)
|
||||||
compile("spec/test_return_token_from_pattern.#{language}", language: language)
|
compile("spec/test_return_token_from_pattern.#{language}", language: language)
|
||||||
results = run
|
results = run
|
||||||
@ -386,7 +434,31 @@ EOF
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "supports lexer modes" do
|
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;
|
import std.stdio;
|
||||||
>>
|
>>
|
||||||
@ -407,6 +479,7 @@ string: /"/ <<
|
|||||||
>>
|
>>
|
||||||
Start -> abc string def;
|
Start -> abc string def;
|
||||||
EOF
|
EOF
|
||||||
|
end
|
||||||
build_parser(language: language)
|
build_parser(language: language)
|
||||||
compile("spec/test_lexer_modes.#{language}", language: language)
|
compile("spec/test_lexer_modes.#{language}", language: language)
|
||||||
results = run
|
results = run
|
||||||
@ -422,7 +495,26 @@ EOF
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "executes user code associated with a parser rule" do
|
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;
|
import std.stdio;
|
||||||
>>
|
>>
|
||||||
@ -438,6 +530,7 @@ B -> b <<
|
|||||||
writeln("B!");
|
writeln("B!");
|
||||||
>>
|
>>
|
||||||
EOF
|
EOF
|
||||||
|
end
|
||||||
build_parser(language: language)
|
build_parser(language: language)
|
||||||
compile("spec/test_parser_rule_user_code.#{language}", language: language)
|
compile("spec/test_parser_rule_user_code.#{language}", language: language)
|
||||||
results = run
|
results = run
|
||||||
@ -451,7 +544,7 @@ EOF
|
|||||||
|
|
||||||
it "parses lists" do
|
it "parses lists" do
|
||||||
write_grammar <<EOF
|
write_grammar <<EOF
|
||||||
ptype uint;
|
ptype #{language == "c" ? "uint32_t" : "uint"};
|
||||||
token a;
|
token a;
|
||||||
Start -> As <<
|
Start -> As <<
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
@ -490,7 +583,23 @@ EOF
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "provides matched text to user code blocks" do
|
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;
|
import std.stdio;
|
||||||
>>
|
>>
|
||||||
@ -499,6 +608,7 @@ token id /[a-zA-Z_][a-zA-Z0-9_]*/ <<
|
|||||||
>>
|
>>
|
||||||
Start -> id;
|
Start -> id;
|
||||||
EOF
|
EOF
|
||||||
|
end
|
||||||
build_parser(language: language)
|
build_parser(language: language)
|
||||||
compile("spec/test_lexer_match_text.#{language}", language: language)
|
compile("spec/test_lexer_match_text.#{language}", language: language)
|
||||||
results = run
|
results = run
|
||||||
@ -510,7 +620,19 @@ EOF
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "allows storing a result value for the lexer" do
|
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;
|
ptype ulong;
|
||||||
token word /[a-z]+/ <<
|
token word /[a-z]+/ <<
|
||||||
$$ = match.length;
|
$$ = match.length;
|
||||||
@ -519,6 +641,7 @@ Start -> word <<
|
|||||||
$$ = $1;
|
$$ = $1;
|
||||||
>>
|
>>
|
||||||
EOF
|
EOF
|
||||||
|
end
|
||||||
build_parser(language: language)
|
build_parser(language: language)
|
||||||
compile("spec/test_lexer_result_value.#{language}", language: language)
|
compile("spec/test_lexer_result_value.#{language}", language: language)
|
||||||
results = run
|
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";
|
input = "a 12\n\na\n\n77\na \xAA";
|
||||||
p_context_init(&context, input);
|
p_context_init(&context, input);
|
||||||
assert(p_parse(&context) == P_DECODE_ERROR);
|
assert(p_parse(&context) == P_DECODE_ERROR);
|
||||||
writeln(p_position(&context));
|
|
||||||
assert(p_position(&context) == p_position_t(5, 4));
|
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