Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ebcbb2d6d | ||
|
|
61ebbb4f19 | ||
|
|
1b4ca59158 | ||
|
|
b02c9205c0 | ||
|
|
7344554b5f | ||
|
|
77571a3449 | ||
|
|
e098b7e445 |
No files matched your search
@@ -1,3 +1,15 @@
|
|||||||
|
## v2.1.1
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
- Field aliases for AST node fields could alias incorrect field when multiple rule alternatives present for one rule set (#33)
|
||||||
|
|
||||||
|
## v2.1.0
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
|
||||||
|
- Report rule name and line number for conflicting AST node field positions errors (#32)
|
||||||
|
|
||||||
## v2.0.0
|
## v2.0.0
|
||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
|
|||||||
+20
-18
@@ -1,34 +1,36 @@
|
|||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
diff-lcs (1.5.0)
|
date (3.4.1)
|
||||||
docile (1.4.0)
|
diff-lcs (1.5.1)
|
||||||
psych (5.1.0)
|
docile (1.4.1)
|
||||||
|
psych (5.2.2)
|
||||||
|
date
|
||||||
stringio
|
stringio
|
||||||
rake (13.0.6)
|
rake (13.2.1)
|
||||||
rdoc (6.5.0)
|
rdoc (6.10.0)
|
||||||
psych (>= 4.0.0)
|
psych (>= 4.0.0)
|
||||||
redcarpet (3.6.0)
|
redcarpet (3.6.0)
|
||||||
rspec (3.12.0)
|
rspec (3.13.0)
|
||||||
rspec-core (~> 3.12.0)
|
rspec-core (~> 3.13.0)
|
||||||
rspec-expectations (~> 3.12.0)
|
rspec-expectations (~> 3.13.0)
|
||||||
rspec-mocks (~> 3.12.0)
|
rspec-mocks (~> 3.13.0)
|
||||||
rspec-core (3.12.2)
|
rspec-core (3.13.2)
|
||||||
rspec-support (~> 3.12.0)
|
rspec-support (~> 3.13.0)
|
||||||
rspec-expectations (3.12.3)
|
rspec-expectations (3.13.3)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.12.0)
|
rspec-support (~> 3.13.0)
|
||||||
rspec-mocks (3.12.6)
|
rspec-mocks (3.13.2)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.12.0)
|
rspec-support (~> 3.13.0)
|
||||||
rspec-support (3.12.1)
|
rspec-support (3.13.2)
|
||||||
simplecov (0.22.0)
|
simplecov (0.22.0)
|
||||||
docile (~> 1.1)
|
docile (~> 1.1)
|
||||||
simplecov-html (~> 0.11)
|
simplecov-html (~> 0.11)
|
||||||
simplecov_json_formatter (~> 0.1)
|
simplecov_json_formatter (~> 0.1)
|
||||||
simplecov-html (0.12.3)
|
simplecov-html (0.13.1)
|
||||||
simplecov_json_formatter (0.1.4)
|
simplecov_json_formatter (0.1.4)
|
||||||
stringio (3.0.7)
|
stringio (3.1.2)
|
||||||
syntax (1.2.2)
|
syntax (1.2.2)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
|
|||||||
+12
-12
@@ -119,6 +119,8 @@ class Propane
|
|||||||
def build_ast_fields(grammar)
|
def build_ast_fields(grammar)
|
||||||
field_ast_node_indexes = {}
|
field_ast_node_indexes = {}
|
||||||
field_indexes_across_all_rules = {}
|
field_indexes_across_all_rules = {}
|
||||||
|
# Stores the index into @ast_fields by field alias name.
|
||||||
|
field_aliases = {}
|
||||||
@ast_fields = []
|
@ast_fields = []
|
||||||
@rules.each do |rule|
|
@rules.each do |rule|
|
||||||
rule.components.each_with_index do |component, i|
|
rule.components.each_with_index do |component, i|
|
||||||
@@ -136,6 +138,16 @@ class Propane
|
|||||||
field_ast_node_indexes[field_name] = @ast_fields.size
|
field_ast_node_indexes[field_name] = @ast_fields.size
|
||||||
@ast_fields << {field_name => struct_name}
|
@ast_fields << {field_name => struct_name}
|
||||||
end
|
end
|
||||||
|
rule.aliases.each do |alias_name, index|
|
||||||
|
if index == i
|
||||||
|
alias_ast_fields_index = field_ast_node_indexes[field_name]
|
||||||
|
if field_aliases[alias_name] && field_aliases[alias_name] != alias_ast_fields_index
|
||||||
|
raise Error.new("Error: conflicting AST node field positions for alias `#{alias_name}` in rule #{rule.name} defined on line #{rule.line_number}")
|
||||||
|
end
|
||||||
|
field_aliases[alias_name] = alias_ast_fields_index
|
||||||
|
@ast_fields[alias_ast_fields_index][alias_name] = @ast_fields[alias_ast_fields_index].first[1]
|
||||||
|
end
|
||||||
|
end
|
||||||
field_indexes_across_all_rules[node_name] ||= Set.new
|
field_indexes_across_all_rules[node_name] ||= Set.new
|
||||||
field_indexes_across_all_rules[node_name] << field_ast_node_indexes[field_name]
|
field_indexes_across_all_rules[node_name] << field_ast_node_indexes[field_name]
|
||||||
rule.rule_set_node_field_index_map[i] = field_ast_node_indexes[field_name]
|
rule.rule_set_node_field_index_map[i] = field_ast_node_indexes[field_name]
|
||||||
@@ -150,18 +162,6 @@ class Propane
|
|||||||
"#{grammar.ast_prefix}#{node_name}#{grammar.ast_suffix}"
|
"#{grammar.ast_prefix}#{node_name}#{grammar.ast_suffix}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# Now merge in the field aliases as given by the user in the
|
|
||||||
# grammar.
|
|
||||||
field_aliases = {}
|
|
||||||
@rules.each do |rule|
|
|
||||||
rule.aliases.each do |alias_name, index|
|
|
||||||
if field_aliases[alias_name] && field_aliases[alias_name] != index
|
|
||||||
raise Error.new("Error: conflicting AST node field positions for alias `#{alias_name}`")
|
|
||||||
end
|
|
||||||
field_aliases[alias_name] = index
|
|
||||||
@ast_fields[index][alias_name] = @ast_fields[index].first[1]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
class Propane
|
class Propane
|
||||||
VERSION = "2.0.0"
|
VERSION = "2.1.1"
|
||||||
end
|
end
|
||||||
@@ -1219,6 +1219,29 @@ EOF
|
|||||||
expect(results.status).to eq 0
|
expect(results.status).to eq 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "aliases the correct field when multiple rules are in a rule set in AST mode" do
|
||||||
|
write_grammar <<EOF
|
||||||
|
ast;
|
||||||
|
|
||||||
|
token a;
|
||||||
|
token b;
|
||||||
|
token c;
|
||||||
|
drop /\\s+/;
|
||||||
|
Start -> a;
|
||||||
|
Start -> Foo;
|
||||||
|
Start -> T:first T:second T:third;
|
||||||
|
Foo -> b;
|
||||||
|
T -> a;
|
||||||
|
T -> b;
|
||||||
|
T -> c;
|
||||||
|
EOF
|
||||||
|
run_propane(language: language)
|
||||||
|
compile("spec/test_ast_field_aliases.#{language}", language: language)
|
||||||
|
results = run_test
|
||||||
|
expect(results.stderr).to eq ""
|
||||||
|
expect(results.status).to eq 0
|
||||||
|
end
|
||||||
|
|
||||||
it "allows specifying field aliases when AST mode is not enabled" do
|
it "allows specifying field aliases when AST mode is not enabled" do
|
||||||
if language == "d"
|
if language == "d"
|
||||||
write_grammar <<EOF
|
write_grammar <<EOF
|
||||||
@@ -1253,6 +1276,56 @@ Start -> id:first id:second <<
|
|||||||
printf("first is %s\\n", ${first});
|
printf("first is %s\\n", ${first});
|
||||||
printf("second is %s\\n", ${second});
|
printf("second is %s\\n", ${second});
|
||||||
>>
|
>>
|
||||||
|
EOF
|
||||||
|
end
|
||||||
|
run_propane(language: language)
|
||||||
|
compile("spec/test_field_aliases.#{language}", language: language)
|
||||||
|
results = run_test
|
||||||
|
expect(results.stderr).to eq ""
|
||||||
|
expect(results.status).to eq 0
|
||||||
|
expect(results.stdout).to match /first is foo1.*second is bar2/m
|
||||||
|
end
|
||||||
|
|
||||||
|
it "aliases the correct field when multiple rules are in a rule set when AST mode is not enabled" do
|
||||||
|
if language == "d"
|
||||||
|
write_grammar <<EOF
|
||||||
|
<<
|
||||||
|
import std.stdio;
|
||||||
|
>>
|
||||||
|
ptype string;
|
||||||
|
token id /[a-zA-Z_][a-zA-Z0-9_]*/ <<
|
||||||
|
$$ = match;
|
||||||
|
>>
|
||||||
|
drop /\\s+/;
|
||||||
|
Start -> id;
|
||||||
|
Start -> Foo;
|
||||||
|
Start -> id:first id:second <<
|
||||||
|
writeln("first is ", ${first});
|
||||||
|
writeln("second is ", ${second});
|
||||||
|
>>
|
||||||
|
Foo -> ;
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
write_grammar <<EOF
|
||||||
|
<<
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
>>
|
||||||
|
ptype char const *;
|
||||||
|
token id /[a-zA-Z_][a-zA-Z0-9_]*/ <<
|
||||||
|
char * s = malloc(match_length + 1);
|
||||||
|
strncpy(s, (char const *)match, match_length);
|
||||||
|
s[match_length] = 0;
|
||||||
|
$$ = s;
|
||||||
|
>>
|
||||||
|
drop /\\s+/;
|
||||||
|
Start -> id;
|
||||||
|
Start -> Foo;
|
||||||
|
Start -> id:first id:second <<
|
||||||
|
printf("first is %s\\n", ${first});
|
||||||
|
printf("second is %s\\n", ${second});
|
||||||
|
>>
|
||||||
|
Foo -> ;
|
||||||
EOF
|
EOF
|
||||||
end
|
end
|
||||||
run_propane(language: language)
|
run_propane(language: language)
|
||||||
|
|||||||
Reference in new issue
Block a user