generates a parser specs passing
This commit is contained in:
parent
aef5367378
commit
35acdde09f
@ -29,7 +29,7 @@ describe Propane do
|
||||
end
|
||||
case options[:language]
|
||||
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"
|
||||
result = system(*%w[ldc2 --unittest -of spec/run/testparser -Ispec], *parsers, *test_files, "spec/testutils.d")
|
||||
end
|
||||
@ -156,7 +156,61 @@ EOF
|
||||
end
|
||||
|
||||
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;
|
||||
>>
|
||||
@ -207,6 +261,7 @@ E4 -> lparen E1 rparen <<
|
||||
$$ = $2;
|
||||
>>
|
||||
EOF
|
||||
end
|
||||
build_parser(language: language)
|
||||
compile("spec/test_basic_math_grammar.#{language}", language: language)
|
||||
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