Support C++ output language
This commit is contained in:
1 parent
ac8ed4bf5a
commit
072af73b1e
12 files changed
+80
-46
No files matched your search
@@ -120,11 +120,11 @@ string: /\\t/ <<
|
||||
>>
|
||||
string: /\\u[0-9a-fA-F]{4}/ <<
|
||||
/* Not actually going to encode the code point for this example... */
|
||||
char s[] = {'{', match[2], match[3], match[4], match[5], '}', 0};
|
||||
char s[] = {'{', (char)match[2], (char)match[3], (char)match[4], (char)match[5], '}', 0};
|
||||
str_append(&string_value, s);
|
||||
>>
|
||||
string: /[^\\]/ <<
|
||||
char s[] = {match[0], 0};
|
||||
char s[] = {(char)match[0], 0};
|
||||
str_append(&string_value, s);
|
||||
>>
|
||||
Start -> Value <<
|
||||
|
||||
+3
-3
@@ -5,7 +5,7 @@
|
||||
|
||||
JSONValue * JSONValue_new(size_t id)
|
||||
{
|
||||
JSONValue * jv = calloc(1, sizeof(JSONValue));
|
||||
JSONValue * jv = (JSONValue *)calloc(1, sizeof(JSONValue));
|
||||
jv->id = id;
|
||||
return jv;
|
||||
}
|
||||
@@ -29,7 +29,7 @@ void JSONObject_append(JSONValue * object, char const * name, JSONValue * value)
|
||||
}
|
||||
}
|
||||
size_t const new_size = size + 1;
|
||||
void * new_entries = malloc(sizeof(object->object.entries[0]) * new_size);
|
||||
JSONObjectEntry * new_entries = (JSONObjectEntry *)malloc(sizeof(object->object.entries[0]) * new_size);
|
||||
if (size > 0)
|
||||
{
|
||||
memcpy(new_entries, object->object.entries, size * sizeof(object->object.entries[0]));
|
||||
@@ -52,7 +52,7 @@ void JSONArray_append(JSONValue * array, JSONValue * value)
|
||||
{
|
||||
size_t const size = array->array.size;
|
||||
size_t const new_size = size + 1;
|
||||
JSONValue ** new_entries = malloc(sizeof(JSONValue *) * new_size);
|
||||
JSONValue ** new_entries = (JSONValue **)malloc(sizeof(JSONValue *) * new_size);
|
||||
if (array->array.size > 0)
|
||||
{
|
||||
memcpy(new_entries, array->array.entries, sizeof(JSONValue *) * size);
|
||||
|
||||
+7
-5
@@ -11,6 +11,12 @@
|
||||
#define JSON_FALSE 5u
|
||||
#define JSON_NULL 6u
|
||||
|
||||
typedef struct JSONObjectEntry_s
|
||||
{
|
||||
char const * name;
|
||||
struct JSONValue_s * value;
|
||||
} JSONObjectEntry;
|
||||
|
||||
typedef struct JSONValue_s
|
||||
{
|
||||
size_t id;
|
||||
@@ -19,11 +25,7 @@ typedef struct JSONValue_s
|
||||
struct
|
||||
{
|
||||
size_t size;
|
||||
struct
|
||||
{
|
||||
char const * name;
|
||||
struct JSONValue_s * value;
|
||||
} * entries;
|
||||
JSONObjectEntry * entries;
|
||||
} object;
|
||||
struct
|
||||
{
|
||||
|
||||
+34
-23
@@ -65,17 +65,26 @@ EOF
|
||||
end
|
||||
|
||||
def compile(test_files, options = {})
|
||||
test_files = Array(test_files)
|
||||
test_files = Array(test_files).map do |test_file|
|
||||
if !File.exist?(test_file) && test_file.end_with?(".cpp")
|
||||
test_file.sub(%r{\.cpp$}, ".c")
|
||||
else
|
||||
test_file
|
||||
end
|
||||
end
|
||||
options[:parsers] ||= [""]
|
||||
parsers = options[:parsers].map do |name|
|
||||
"spec/run/testparser#{name}.#{options[:language]}"
|
||||
end
|
||||
case options[:language]
|
||||
when "c"
|
||||
result = system(*%w[gcc -Wall -o spec/run/testparser -Ispec -Ispec/run], *parsers, *test_files, "spec/testutils.c", "-lm")
|
||||
command = [*%w[gcc -Wall -o spec/run/testparser -Ispec -Ispec/run], *parsers, *test_files, "spec/testutils.c", "-lm"]
|
||||
when "cpp"
|
||||
command = [*%w[g++ -x c++ -Wall -o spec/run/testparser -Ispec -Ispec/run], *parsers, *test_files, "spec/testutils.c", "-lm"]
|
||||
when "d"
|
||||
result = system(*%w[ldc2 -g --unittest -of spec/run/testparser -Ispec], *parsers, *test_files, "spec/testutils.d")
|
||||
command = [*%w[ldc2 -g --unittest -of spec/run/testparser -Ispec], *parsers, *test_files, "spec/testutils.d"]
|
||||
end
|
||||
result = system(*command)
|
||||
expect(result).to be_truthy
|
||||
end
|
||||
|
||||
@@ -261,7 +270,7 @@ EOF
|
||||
expect(results.status).to_not eq 0
|
||||
end
|
||||
|
||||
%w[d c].each do |language|
|
||||
%w[d c cpp].each do |language|
|
||||
|
||||
context "#{language.upcase} language" do
|
||||
|
||||
@@ -284,7 +293,7 @@ EOF
|
||||
|
||||
it "detects a lexer error when an unknown character is seen" do
|
||||
case language
|
||||
when "c"
|
||||
when "c", "cpp"
|
||||
write_grammar <<EOF
|
||||
ptype int;
|
||||
token int /\\d+/ <<
|
||||
@@ -338,7 +347,7 @@ EOF
|
||||
|
||||
it "generates a parser that does basic math - user guide example" do
|
||||
case language
|
||||
when "c"
|
||||
when "c", "cpp"
|
||||
write_grammar <<EOF
|
||||
<<
|
||||
#include <math.h>
|
||||
@@ -456,7 +465,7 @@ EOF
|
||||
|
||||
it "executes user code when matching lexer token" do
|
||||
case language
|
||||
when "c"
|
||||
when "c", "cpp"
|
||||
write_grammar <<EOF
|
||||
<<
|
||||
#include <stdio.h>
|
||||
@@ -498,7 +507,7 @@ EOF
|
||||
|
||||
it "supports a pattern statement" do
|
||||
case language
|
||||
when "c"
|
||||
when "c", "cpp"
|
||||
write_grammar <<EOF
|
||||
<<
|
||||
#include <stdio.h>
|
||||
@@ -534,7 +543,7 @@ EOF
|
||||
|
||||
it "supports returning tokens from pattern code blocks" do
|
||||
case language
|
||||
when "c"
|
||||
when "c", "cpp"
|
||||
write_grammar <<EOF
|
||||
<<
|
||||
#include <stdio.h>
|
||||
@@ -574,7 +583,7 @@ EOF
|
||||
|
||||
it "supports lexer modes" do
|
||||
case language
|
||||
when "c"
|
||||
when "c", "cpp"
|
||||
write_grammar <<EOF
|
||||
<<
|
||||
#include <stdio.h>
|
||||
@@ -635,7 +644,7 @@ EOF
|
||||
|
||||
it "multiple lexer modes may apply to a pattern" do
|
||||
case language
|
||||
when "c"
|
||||
when "c", "cpp"
|
||||
write_grammar <<EOF
|
||||
<<
|
||||
#include <stdio.h>
|
||||
@@ -691,7 +700,7 @@ EOF
|
||||
|
||||
it "executes user code associated with a parser rule" do
|
||||
case language
|
||||
when "c"
|
||||
when "c", "cpp"
|
||||
write_grammar <<EOF
|
||||
<<
|
||||
#include <stdio.h>
|
||||
@@ -727,7 +736,7 @@ EOF
|
||||
|
||||
it "parses lists" do
|
||||
write_grammar <<EOF
|
||||
ptype #{language == "c" ? "uint32_t" : "uint"};
|
||||
ptype #{language == "d" ? "uint" : "uint32_t"};
|
||||
token a;
|
||||
Start -> As << $$ = $1; >>
|
||||
As -> << $$ = 0u; >>
|
||||
@@ -762,14 +771,14 @@ EOF
|
||||
|
||||
it "provides matched text to user code blocks" do
|
||||
case language
|
||||
when "c"
|
||||
when "c", "cpp"
|
||||
write_grammar <<EOF
|
||||
<<
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
>>
|
||||
token id /[a-zA-Z_][a-zA-Z0-9_]*/ <<
|
||||
char * t = malloc(match_length + 1);
|
||||
char * t = (char *)malloc(match_length + 1);
|
||||
strncpy(t, (char *)match, match_length);
|
||||
printf("Matched token is %s\\n", t);
|
||||
free(t);
|
||||
@@ -799,7 +808,7 @@ EOF
|
||||
|
||||
it "allows storing a result value for the lexer" do
|
||||
case language
|
||||
when "c"
|
||||
when "c", "cpp"
|
||||
write_grammar <<EOF
|
||||
ptype uint64_t;
|
||||
token word /[a-z]+/ <<
|
||||
@@ -843,7 +852,8 @@ EOF
|
||||
end
|
||||
|
||||
it "allows creating a JSON parser" do
|
||||
write_grammar(File.read("spec/json_parser.#{language}.propane"))
|
||||
ext = language == "cpp" ? "c" : language
|
||||
write_grammar(File.read("spec/json_parser.#{ext}.propane"))
|
||||
run_propane(language: language)
|
||||
compile(["spec/test_parsing_json.#{language}", "spec/json_types.#{language}"], language: language)
|
||||
end
|
||||
@@ -909,7 +919,7 @@ EOF
|
||||
|
||||
it "matches backslash escape sequences" do
|
||||
case language
|
||||
when "c"
|
||||
when "c", "cpp"
|
||||
write_grammar <<EOF
|
||||
<<
|
||||
#include <stdio.h>
|
||||
@@ -1123,8 +1133,8 @@ Start -> a? b R? <<
|
||||
printf("b: %d\\n", $2);
|
||||
printf("R: %s\\n", $3 == NULL ? "" : $3);
|
||||
>>
|
||||
R -> c d << $$ = "cd"; >>
|
||||
R (string) -> d c << $$ = "dc"; >>
|
||||
R -> c d << $$ = (char *)"cd"; >>
|
||||
R (string) -> d c << $$ = (char *)"dc"; >>
|
||||
EOF
|
||||
end
|
||||
run_propane(language: language)
|
||||
@@ -1334,7 +1344,7 @@ EOF
|
||||
>>
|
||||
ptype char const *;
|
||||
token id /[a-zA-Z_][a-zA-Z0-9_]*/ <<
|
||||
char * s = malloc(match_length + 1);
|
||||
char * s = (char *)malloc(match_length + 1);
|
||||
strncpy(s, (char const *)match, match_length);
|
||||
s[match_length] = 0;
|
||||
$$ = s;
|
||||
@@ -1381,7 +1391,7 @@ EOF
|
||||
>>
|
||||
ptype char const *;
|
||||
token id /[a-zA-Z_][a-zA-Z0-9_]*/ <<
|
||||
char * s = malloc(match_length + 1);
|
||||
char * s = (char *)malloc(match_length + 1);
|
||||
strncpy(s, (char const *)match, match_length);
|
||||
s[match_length] = 0;
|
||||
$$ = s;
|
||||
@@ -1405,7 +1415,8 @@ EOF
|
||||
end
|
||||
|
||||
it "does not free memory allocated for AST nodes" do
|
||||
write_grammar(File.read("spec/ast_node_memory_remains.#{language}.propane"))
|
||||
ext = language == "cpp" ? "c" : language
|
||||
write_grammar(File.read("spec/ast_node_memory_remains.#{ext}.propane"))
|
||||
run_propane(language: language)
|
||||
compile("spec/test_ast_node_memory_remains.#{language}", language: language)
|
||||
results = run_test
|
||||
|
||||
@@ -2,6 +2,10 @@ unless ENV["dist_specs"]
|
||||
require "bundler/setup"
|
||||
require "simplecov"
|
||||
|
||||
class MyFormatter
|
||||
def format(*args)
|
||||
end
|
||||
end
|
||||
SimpleCov.start do
|
||||
add_filter "/spec/"
|
||||
add_filter "/.bundle/"
|
||||
@@ -12,6 +16,7 @@ unless ENV["dist_specs"]
|
||||
end
|
||||
project_name "Propane"
|
||||
merge_timeout 3600
|
||||
formatter(MyFormatter)
|
||||
end
|
||||
|
||||
RSpec.configure do |config|
|
||||
|
||||
@@ -386,7 +386,7 @@ int main(int argc, char * argv[])
|
||||
}
|
||||
pmis = pmis->pModuleItems;
|
||||
}
|
||||
pfds = malloc(n_pfds * sizeof(PModuleItems *));
|
||||
pfds = (PFunctionDefinition **)malloc(n_pfds * sizeof(PModuleItems *));
|
||||
pmis = pmod->pModuleItems;
|
||||
size_t pfd_i = n_pfds;
|
||||
while (pmis != NULL)
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@ void assert_eq_size_t_i(size_t expected, size_t actual, char const * file, size_
|
||||
void str_init(str_t * str, char const * cs)
|
||||
{
|
||||
size_t length = strlen(cs);
|
||||
str->cs = malloc(length + 1u);
|
||||
str->cs = (char *)malloc(length + 1u);
|
||||
strcpy(str->cs, cs);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ void str_append(str_t * str, char const * cs)
|
||||
{
|
||||
size_t length = strlen(str->cs);
|
||||
size_t length2 = strlen(cs);
|
||||
char * new_cs = malloc(length + length2 + 1u);
|
||||
char * new_cs = (char *)malloc(length + length2 + 1u);
|
||||
memcpy(new_cs, str->cs, length);
|
||||
strcpy(&new_cs[length], cs);
|
||||
free(str->cs);
|
||||
|
||||
Reference in new issue
Block a user