Compare commits
5
Commits
v4.4.0
..
232af68081
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
232af68081 | ||
|
|
23834bef82 | ||
|
|
7b698d7b31 | ||
|
|
45843da0df | ||
|
|
f27a8688f7 |
No files matched your search
@@ -1,3 +1,21 @@
|
||||
## v4.5.0
|
||||
|
||||
### New Features
|
||||
|
||||
- Add `noline` grammar statement to skip emitting `#line` directives
|
||||
- Attempt to autodetect target language (D/C++) in extra/vim/syntax/propane.vim
|
||||
|
||||
### Fixes
|
||||
|
||||
- Fix #line reset directives
|
||||
- Update keyword list in extra/vim/syntax/propane.vim
|
||||
|
||||
## v4.4.0
|
||||
|
||||
### New Features
|
||||
|
||||
- Add p_value_get() / p_value_get_XXX() accessors
|
||||
|
||||
## v4.3.0
|
||||
|
||||
### New Features
|
||||
|
||||
@@ -383,6 +383,27 @@ module proj.parser;
|
||||
If a module statement is not present, then the generated D module will not
|
||||
contain a module statement and the default module name will be used.
|
||||
|
||||
##> `noline` statement - disabling `#line` directives
|
||||
|
||||
By default, Propane emits `#line` directives into the generated output around
|
||||
user code blocks.
|
||||
These directives instruct the compiler to report any warnings or errors in the
|
||||
user code using the file name and line number of the original grammar file,
|
||||
rather than the generated output file.
|
||||
This makes it easier to locate the source of a compiler diagnostic in the
|
||||
grammar file.
|
||||
|
||||
The `noline` statement disables the emission of these `#line` directives.
|
||||
|
||||
```
|
||||
noline;
|
||||
```
|
||||
|
||||
When the `noline` statement is present, user code blocks are copied to the
|
||||
generated output without any surrounding `#line` directives.
|
||||
This can be useful when debugging the generated parser itself, or when the
|
||||
`#line` directives interfere with other tooling.
|
||||
|
||||
##> `on_tree_node` statement - custom initialization of a token tree node
|
||||
|
||||
The `on_token_node` statement can be used to provide code that initializes
|
||||
|
||||
@@ -8,7 +8,11 @@ if exists("b:current_syntax")
|
||||
endif
|
||||
|
||||
if !exists("b:propane_subtype")
|
||||
let b:propane_subtype = "d"
|
||||
if search('\<import\s\+\%(std\|core\)\.', 'nw') > 0
|
||||
let b:propane_subtype = "d"
|
||||
else
|
||||
let b:propane_subtype = "cpp"
|
||||
endif
|
||||
endif
|
||||
|
||||
exe "syn include @propaneTarget syntax/".b:propane_subtype.".vim"
|
||||
@@ -20,7 +24,7 @@ syn match propaneOperator "->"
|
||||
syn match propaneFieldAlias ":[a-zA-Z0-9_]\+" contains=propaneFieldOperator
|
||||
syn match propaneFieldOperator ":" contained
|
||||
syn match propaneOperator "?"
|
||||
syn keyword propaneKeyword drop free_token_node free_token_user_fields module prefix ptype start token token_user_fields tokenid tree tree_prefix tree_suffix
|
||||
syn keyword propaneKeyword context_user_fields drop free_token_node lex_fn module noline on_token_node prefix ptype start token token_user_fields tokenid tree tree_prefix tree_suffix
|
||||
|
||||
syn region propaneRegex start="/" end="/" skip="\v\\\\|\\/"
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ class Propane
|
||||
erb = ERB.new(template, trim_mode: "<>")
|
||||
result = erb.result(binding.clone).lines.each_with_index.map do |line, i|
|
||||
if line == "#linereset\n"
|
||||
"#line #{i + 2}\n"
|
||||
%[#line #{i + 2} "#{output_file}"\n]
|
||||
else
|
||||
line
|
||||
end
|
||||
|
||||
+20
-8
@@ -88,6 +88,7 @@ class Propane
|
||||
elsif parse_rule_statement!
|
||||
elsif parse_code_block_statement!
|
||||
elsif parse_prefix_statement!
|
||||
elsif parse_noline_statement!
|
||||
else
|
||||
if @input.size > 25
|
||||
@input = @input.slice(0..20) + "..."
|
||||
@@ -306,10 +307,12 @@ class Propane
|
||||
if md = consume!(/<<([a-z]*)(.*?)>>\n/m)
|
||||
name, code = md[1..2]
|
||||
code = code.chomp
|
||||
if code.start_with?("\n")
|
||||
code = %[#line #{@line_number + 1} "#{@filename}"#{code}\n#linereset\n]
|
||||
else
|
||||
code = %[#line #{@line_number} "#{@filename}"\n#{code}\n#linereset\n]
|
||||
unless @noline
|
||||
if code.start_with?("\n")
|
||||
code = %[#line #{@line_number + 1} "#{@filename}"#{code}\n#linereset\n]
|
||||
else
|
||||
code = %[#line #{@line_number} "#{@filename}"\n#{code}\n#linereset\n]
|
||||
end
|
||||
end
|
||||
if @code_blocks[name]
|
||||
@code_blocks[name] += code
|
||||
@@ -328,6 +331,13 @@ class Propane
|
||||
end
|
||||
end
|
||||
|
||||
def parse_noline_statement!
|
||||
if md = consume!(/noline\s*;/)
|
||||
@noline = true
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def parse_pattern!
|
||||
if md = consume!(%r{/})
|
||||
pattern = ""
|
||||
@@ -352,10 +362,12 @@ class Propane
|
||||
def parse_code_block!
|
||||
if md = consume!(/<<(.*?)>>\n/m)
|
||||
code = md[1].chomp
|
||||
if code.start_with?("\n")
|
||||
code = %[#line #{@line_number + 1} "#{@filename}"#{code}\n#linereset\n]
|
||||
else
|
||||
code = %[#line #{@line_number} "#{@filename}"\n#{code}\n#linereset\n]
|
||||
unless @noline
|
||||
if code.start_with?("\n")
|
||||
code = %[#line #{@line_number + 1} "#{@filename}"#{code}\n#linereset\n]
|
||||
else
|
||||
code = %[#line #{@line_number} "#{@filename}"\n#{code}\n#linereset\n]
|
||||
end
|
||||
end
|
||||
code
|
||||
end
|
||||
|
||||
@@ -133,6 +133,41 @@ EOF
|
||||
expect(o.code).to eq %[#line 7 "test.propane"\n writeln("Hello there");\n#linereset\n]
|
||||
end
|
||||
|
||||
it "does not emit #line directives with noline statement" do
|
||||
input = <<EOF
|
||||
noline;
|
||||
|
||||
token code1 <<
|
||||
a = b;
|
||||
return c;
|
||||
>>
|
||||
|
||||
token code2 <<
|
||||
writeln("Hello there");
|
||||
>>
|
||||
|
||||
tokenid token_with_no_pattern;
|
||||
|
||||
prefix myparser_;
|
||||
EOF
|
||||
grammar = Grammar.new(input, "test.propane")
|
||||
expect(grammar.prefix).to eq "myparser_"
|
||||
|
||||
o = grammar.tokens.find {|token| token.name == "code1"}
|
||||
expect(o).to_not be_nil
|
||||
|
||||
o = grammar.patterns.find {|pattern| pattern.token == o}
|
||||
expect(o).to_not be_nil
|
||||
expect(o.code).to eq %[\n a = b;\n return c;]
|
||||
|
||||
o = grammar.tokens.find {|token| token.name == "code2"}
|
||||
expect(o).to_not be_nil
|
||||
|
||||
o = grammar.patterns.find {|pattern| pattern.token == o}
|
||||
expect(o).to_not be_nil
|
||||
expect(o.code).to eq %[\n writeln("Hello there");]
|
||||
end
|
||||
|
||||
it "supports mode labels" do
|
||||
input = <<EOF
|
||||
token a;
|
||||
|
||||
Reference in new issue
Block a user