generates a parser specs passing
This commit is contained in:
parent
aef5367378
commit
35acdde09f
@ -29,7 +29,7 @@ describe Propane do
|
|||||||
end
|
end
|
||||||
case options[:language]
|
case options[:language]
|
||||||
when "c"
|
when "c"
|
||||||
result = system(*%w[gcc -Wall -o spec/run/testparser -Ispec -Ispec/run], *parsers, *test_files)
|
result = system(*%w[gcc -Wall -o spec/run/testparser -Ispec -Ispec/run], *parsers, *test_files, "spec/testutils.c", "-lm")
|
||||||
when "d"
|
when "d"
|
||||||
result = system(*%w[ldc2 --unittest -of spec/run/testparser -Ispec], *parsers, *test_files, "spec/testutils.d")
|
result = system(*%w[ldc2 --unittest -of spec/run/testparser -Ispec], *parsers, *test_files, "spec/testutils.d")
|
||||||
end
|
end
|
||||||
@ -156,7 +156,61 @@ EOF
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "generates a parser that does basic math - user guide example" do
|
it "generates a parser that does basic math - user guide example" do
|
||||||
write_grammar <<EOF
|
case language
|
||||||
|
when "c"
|
||||||
|
write_grammar <<EOF
|
||||||
|
<<
|
||||||
|
#include <math.h>
|
||||||
|
>>
|
||||||
|
|
||||||
|
ptype size_t;
|
||||||
|
|
||||||
|
token plus /\\+/;
|
||||||
|
token times /\\*/;
|
||||||
|
token power /\\*\\*/;
|
||||||
|
token integer /\\d+/ <<
|
||||||
|
size_t v = 0u;
|
||||||
|
for (size_t i = 0u; i < match_length; i++)
|
||||||
|
{
|
||||||
|
v *= 10;
|
||||||
|
v += (match[i] - '0');
|
||||||
|
}
|
||||||
|
$$ = v;
|
||||||
|
>>
|
||||||
|
token lparen /\\(/;
|
||||||
|
token rparen /\\)/;
|
||||||
|
drop /\\s+/;
|
||||||
|
|
||||||
|
Start -> E1 <<
|
||||||
|
$$ = $1;
|
||||||
|
>>
|
||||||
|
E1 -> E2 <<
|
||||||
|
$$ = $1;
|
||||||
|
>>
|
||||||
|
E1 -> E1 plus E2 <<
|
||||||
|
$$ = $1 + $3;
|
||||||
|
>>
|
||||||
|
E2 -> E3 <<
|
||||||
|
$$ = $1;
|
||||||
|
>>
|
||||||
|
E2 -> E2 times E3 <<
|
||||||
|
$$ = $1 * $3;
|
||||||
|
>>
|
||||||
|
E3 -> E4 <<
|
||||||
|
$$ = $1;
|
||||||
|
>>
|
||||||
|
E3 -> E3 power E4 <<
|
||||||
|
$$ = (size_t)pow($1, $3);
|
||||||
|
>>
|
||||||
|
E4 -> integer <<
|
||||||
|
$$ = $1;
|
||||||
|
>>
|
||||||
|
E4 -> lparen E1 rparen <<
|
||||||
|
$$ = $2;
|
||||||
|
>>
|
||||||
|
EOF
|
||||||
|
when "d"
|
||||||
|
write_grammar <<EOF
|
||||||
<<
|
<<
|
||||||
import std.math;
|
import std.math;
|
||||||
>>
|
>>
|
||||||
@ -207,6 +261,7 @@ E4 -> lparen E1 rparen <<
|
|||||||
$$ = $2;
|
$$ = $2;
|
||||||
>>
|
>>
|
||||||
EOF
|
EOF
|
||||||
|
end
|
||||||
build_parser(language: language)
|
build_parser(language: language)
|
||||||
compile("spec/test_basic_math_grammar.#{language}", language: language)
|
compile("spec/test_basic_math_grammar.#{language}", language: language)
|
||||||
results = run
|
results = run
|
||||||
|
29
spec/test_basic_math_grammar.c
Normal file
29
spec/test_basic_math_grammar.c
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include "testparser.h"
|
||||||
|
#include "testutils.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
char const * input = "1 + 2 * 3 + 4";
|
||||||
|
p_context_t context;
|
||||||
|
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||||
|
assert_eq(P_SUCCESS, p_parse(&context));
|
||||||
|
assert_eq(11, p_result(&context));
|
||||||
|
|
||||||
|
input = "1 * 2 ** 4 * 3";
|
||||||
|
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||||
|
assert_eq(P_SUCCESS, p_parse(&context));
|
||||||
|
assert_eq(48, p_result(&context));
|
||||||
|
|
||||||
|
input = "(1 + 2) * 3 + 4";
|
||||||
|
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||||
|
assert_eq(P_SUCCESS, p_parse(&context));
|
||||||
|
assert_eq(13, p_result(&context));
|
||||||
|
|
||||||
|
input = "(2 * 2) ** 3 + 4 + 5";
|
||||||
|
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||||
|
assert_eq(P_SUCCESS, p_parse(&context));
|
||||||
|
assert_eq(73, p_result(&context));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
12
spec/testutils.c
Normal file
12
spec/testutils.c
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
void assert_eq_size_t_i(size_t expected, size_t actual, char const * file, size_t line)
|
||||||
|
{
|
||||||
|
if (expected != actual)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s:%lu: expected %lu, got %lu\n", file, line, expected, actual);
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
7
spec/testutils.h
Normal file
7
spec/testutils.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
void assert_eq_size_t_i(size_t expected, size_t actual, char const * file, size_t line);
|
||||||
|
|
||||||
|
#define assert_eq(expected, actual) \
|
||||||
|
assert_eq_size_t_i(expected, actual, __FILE__, __LINE__)
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user