Add noline grammar statement to skip emitting #line directives
This commit is contained in:
parent
45843da0df
commit
7b698d7b31
@ -1,5 +1,9 @@
|
|||||||
## v4.5.0
|
## v4.5.0
|
||||||
|
|
||||||
|
### New Features
|
||||||
|
|
||||||
|
- Add `noline` grammar statement to skip emitting `#line` directives
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
|
||||||
- Fix #line reset directives
|
- Fix #line reset directives
|
||||||
|
|||||||
@ -383,6 +383,27 @@ module proj.parser;
|
|||||||
If a module statement is not present, then the generated D module will not
|
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.
|
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
|
##> `on_tree_node` statement - custom initialization of a token tree node
|
||||||
|
|
||||||
The `on_token_node` statement can be used to provide code that initializes
|
The `on_token_node` statement can be used to provide code that initializes
|
||||||
|
|||||||
@ -88,6 +88,7 @@ class Propane
|
|||||||
elsif parse_rule_statement!
|
elsif parse_rule_statement!
|
||||||
elsif parse_code_block_statement!
|
elsif parse_code_block_statement!
|
||||||
elsif parse_prefix_statement!
|
elsif parse_prefix_statement!
|
||||||
|
elsif parse_noline_statement!
|
||||||
else
|
else
|
||||||
if @input.size > 25
|
if @input.size > 25
|
||||||
@input = @input.slice(0..20) + "..."
|
@input = @input.slice(0..20) + "..."
|
||||||
@ -306,11 +307,13 @@ class Propane
|
|||||||
if md = consume!(/<<([a-z]*)(.*?)>>\n/m)
|
if md = consume!(/<<([a-z]*)(.*?)>>\n/m)
|
||||||
name, code = md[1..2]
|
name, code = md[1..2]
|
||||||
code = code.chomp
|
code = code.chomp
|
||||||
|
unless @noline
|
||||||
if code.start_with?("\n")
|
if code.start_with?("\n")
|
||||||
code = %[#line #{@line_number + 1} "#{@filename}"#{code}\n#linereset\n]
|
code = %[#line #{@line_number + 1} "#{@filename}"#{code}\n#linereset\n]
|
||||||
else
|
else
|
||||||
code = %[#line #{@line_number} "#{@filename}"\n#{code}\n#linereset\n]
|
code = %[#line #{@line_number} "#{@filename}"\n#{code}\n#linereset\n]
|
||||||
end
|
end
|
||||||
|
end
|
||||||
if @code_blocks[name]
|
if @code_blocks[name]
|
||||||
@code_blocks[name] += code
|
@code_blocks[name] += code
|
||||||
else
|
else
|
||||||
@ -328,6 +331,13 @@ class Propane
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def parse_noline_statement!
|
||||||
|
if md = consume!(/noline\s*;/)
|
||||||
|
@noline = true
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def parse_pattern!
|
def parse_pattern!
|
||||||
if md = consume!(%r{/})
|
if md = consume!(%r{/})
|
||||||
pattern = ""
|
pattern = ""
|
||||||
@ -352,11 +362,13 @@ class Propane
|
|||||||
def parse_code_block!
|
def parse_code_block!
|
||||||
if md = consume!(/<<(.*?)>>\n/m)
|
if md = consume!(/<<(.*?)>>\n/m)
|
||||||
code = md[1].chomp
|
code = md[1].chomp
|
||||||
|
unless @noline
|
||||||
if code.start_with?("\n")
|
if code.start_with?("\n")
|
||||||
code = %[#line #{@line_number + 1} "#{@filename}"#{code}\n#linereset\n]
|
code = %[#line #{@line_number + 1} "#{@filename}"#{code}\n#linereset\n]
|
||||||
else
|
else
|
||||||
code = %[#line #{@line_number} "#{@filename}"\n#{code}\n#linereset\n]
|
code = %[#line #{@line_number} "#{@filename}"\n#{code}\n#linereset\n]
|
||||||
end
|
end
|
||||||
|
end
|
||||||
code
|
code
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -133,6 +133,41 @@ EOF
|
|||||||
expect(o.code).to eq %[#line 7 "test.propane"\n writeln("Hello there");\n#linereset\n]
|
expect(o.code).to eq %[#line 7 "test.propane"\n writeln("Hello there");\n#linereset\n]
|
||||||
end
|
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
|
it "supports mode labels" do
|
||||||
input = <<EOF
|
input = <<EOF
|
||||||
token a;
|
token a;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user