Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b641c64425 | ||
|
|
5245302f49 | ||
|
|
7a140623ff | ||
|
|
42035c3a55 | ||
|
|
d97f0f8f49 | ||
|
|
98e2beb425 | ||
|
|
30565545ee | ||
|
|
cd75077959 | ||
|
|
51b09a5799 |
No files matched your search
@@ -1,3 +1,15 @@
|
|||||||
|
## v4.3.0
|
||||||
|
|
||||||
|
### New Features
|
||||||
|
|
||||||
|
- Use #line for user code blocks to report input grammar position for errors.
|
||||||
|
|
||||||
|
## v4.2.0
|
||||||
|
|
||||||
|
### New Features
|
||||||
|
|
||||||
|
- Add support for a custom lex function.
|
||||||
|
|
||||||
## v4.1.0
|
## v4.1.0
|
||||||
|
|
||||||
### New Features
|
### New Features
|
||||||
|
|||||||
+4
-4
@@ -5,11 +5,11 @@ GEM
|
|||||||
date (3.5.1)
|
date (3.5.1)
|
||||||
diff-lcs (1.6.2)
|
diff-lcs (1.6.2)
|
||||||
docile (1.4.1)
|
docile (1.4.1)
|
||||||
erb (6.0.1)
|
erb (6.0.4)
|
||||||
psych (5.3.1)
|
psych (5.3.1)
|
||||||
date
|
date
|
||||||
stringio
|
stringio
|
||||||
rake (13.3.1)
|
rake (13.4.2)
|
||||||
rdoc (7.2.0)
|
rdoc (7.2.0)
|
||||||
erb
|
erb
|
||||||
psych (>= 4.0.0)
|
psych (>= 4.0.0)
|
||||||
@@ -24,7 +24,7 @@ GEM
|
|||||||
rspec-expectations (3.13.5)
|
rspec-expectations (3.13.5)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.13.0)
|
rspec-support (~> 3.13.0)
|
||||||
rspec-mocks (3.13.7)
|
rspec-mocks (3.13.8)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.13.0)
|
rspec-support (~> 3.13.0)
|
||||||
rspec-support (3.13.7)
|
rspec-support (3.13.7)
|
||||||
@@ -51,4 +51,4 @@ DEPENDENCIES
|
|||||||
syntax
|
syntax
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
2.3.7
|
4.0.11
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2010-2024 Josh Holtrop
|
Copyright (c) 2010-2026 Josh Holtrop
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+1
-1
@@ -33,7 +33,7 @@ class Propane
|
|||||||
|
|
||||||
def run(input_file, output_file, log_file, options)
|
def run(input_file, output_file, log_file, options)
|
||||||
begin
|
begin
|
||||||
grammar = Grammar.new(File.read(input_file))
|
grammar = Grammar.new(File.read(input_file), input_file)
|
||||||
generator = Generator.new(grammar, output_file, log_file, options)
|
generator = Generator.new(grammar, output_file, log_file, options)
|
||||||
generator.generate
|
generator.generate
|
||||||
rescue Error => e
|
rescue Error => e
|
||||||
|
|||||||
@@ -38,7 +38,13 @@ class Propane
|
|||||||
output_file = @output_file
|
output_file = @output_file
|
||||||
end
|
end
|
||||||
erb = ERB.new(template, trim_mode: "<>")
|
erb = ERB.new(template, trim_mode: "<>")
|
||||||
result = erb.result(binding.clone)
|
result = erb.result(binding.clone).lines.each_with_index.map do |line, i|
|
||||||
|
if line == "#linereset\n"
|
||||||
|
"#line #{i + 2}\n"
|
||||||
|
else
|
||||||
|
line
|
||||||
|
end
|
||||||
|
end.join
|
||||||
File.open(output_file, "wb") do |fh|
|
File.open(output_file, "wb") do |fh|
|
||||||
fh.write(result)
|
fh.write(result)
|
||||||
end
|
end
|
||||||
|
|||||||
+14
-6
@@ -22,7 +22,8 @@ class Propane
|
|||||||
attr_reader :on_token_node
|
attr_reader :on_token_node
|
||||||
attr_reader :token_user_fields
|
attr_reader :token_user_fields
|
||||||
|
|
||||||
def initialize(input)
|
def initialize(input, filename)
|
||||||
|
@filename = filename
|
||||||
@patterns = []
|
@patterns = []
|
||||||
@start_rules = []
|
@start_rules = []
|
||||||
@tokens = []
|
@tokens = []
|
||||||
@@ -304,8 +305,12 @@ class Propane
|
|||||||
def parse_code_block_statement!
|
def parse_code_block_statement!
|
||||||
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.sub!(/\A\n/, "")
|
code = code.chomp
|
||||||
code += "\n" unless code.end_with?("\n")
|
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
|
||||||
if @code_blocks[name]
|
if @code_blocks[name]
|
||||||
@code_blocks[name] += code
|
@code_blocks[name] += code
|
||||||
else
|
else
|
||||||
@@ -346,9 +351,12 @@ class Propane
|
|||||||
|
|
||||||
def parse_code_block!
|
def parse_code_block!
|
||||||
if md = consume!(/<<(.*?)>>\n/m)
|
if md = consume!(/<<(.*?)>>\n/m)
|
||||||
code = md[1]
|
code = md[1].chomp
|
||||||
code.sub!(/\A\n/, "")
|
if code.start_with?("\n")
|
||||||
code += "\n" unless code.end_with?("\n")
|
code = %[#line #{@line_number + 1} "#{@filename}"#{code}\n#linereset\n]
|
||||||
|
else
|
||||||
|
code = %[#line #{@line_number} "#{@filename}"\n#{code}\n#linereset\n]
|
||||||
|
end
|
||||||
code
|
code
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
class Propane
|
class Propane
|
||||||
VERSION = "4.1.0"
|
VERSION = "4.3.0"
|
||||||
end
|
end
|
||||||
@@ -28,7 +28,7 @@ B -> <<
|
|||||||
b = 0;
|
b = 0;
|
||||||
>>
|
>>
|
||||||
EOF
|
EOF
|
||||||
grammar = Grammar.new(input)
|
grammar = Grammar.new(input, "test.propane")
|
||||||
expect(grammar.modulename).to eq "a.b"
|
expect(grammar.modulename).to eq "a.b"
|
||||||
expect(grammar.ptype).to eq "XYZ *"
|
expect(grammar.ptype).to eq "XYZ *"
|
||||||
expect(grammar.ptypes).to eq("default" => "XYZ *")
|
expect(grammar.ptypes).to eq("default" => "XYZ *")
|
||||||
@@ -62,7 +62,7 @@ EOF
|
|||||||
expect(o).to_not be_nil
|
expect(o).to_not be_nil
|
||||||
expect(o.pattern).to eq "token_with_code"
|
expect(o.pattern).to eq "token_with_code"
|
||||||
expect(o.line_number).to eq 11
|
expect(o.line_number).to eq 11
|
||||||
expect(o.code).to eq "Code for the token\n"
|
expect(o.code).to eq %[#line 12 "test.propane"\nCode for the token\n#linereset\n]
|
||||||
|
|
||||||
o = grammar.tokens.find {|token| token.name == "token_with_no_pattern"}
|
o = grammar.tokens.find {|token| token.name == "token_with_no_pattern"}
|
||||||
expect(o).to_not be_nil
|
expect(o).to_not be_nil
|
||||||
@@ -83,7 +83,7 @@ EOF
|
|||||||
expect(o.name).to eq "A"
|
expect(o.name).to eq "A"
|
||||||
expect(o.components).to eq %w[B]
|
expect(o.components).to eq %w[B]
|
||||||
expect(o.line_number).to eq 19
|
expect(o.line_number).to eq 19
|
||||||
expect(o.code).to eq " a = 42;\n"
|
expect(o.code).to eq %[#line 20 "test.propane"\n a = 42;\n#linereset\n]
|
||||||
|
|
||||||
o = grammar.rules[1]
|
o = grammar.rules[1]
|
||||||
expect(o.name).to eq "B"
|
expect(o.name).to eq "B"
|
||||||
@@ -95,7 +95,7 @@ EOF
|
|||||||
expect(o.name).to eq "B"
|
expect(o.name).to eq "B"
|
||||||
expect(o.components).to eq []
|
expect(o.components).to eq []
|
||||||
expect(o.line_number).to eq 23
|
expect(o.line_number).to eq 23
|
||||||
expect(o.code).to eq " b = 0;\n"
|
expect(o.code).to eq %[#line 24 "test.propane"\n b = 0;\n#linereset\n]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "parses code segments with semicolons" do
|
it "parses code segments with semicolons" do
|
||||||
@@ -113,7 +113,7 @@ tokenid token_with_no_pattern;
|
|||||||
|
|
||||||
prefix myparser_;
|
prefix myparser_;
|
||||||
EOF
|
EOF
|
||||||
grammar = Grammar.new(input)
|
grammar = Grammar.new(input, "test.propane")
|
||||||
expect(grammar.prefix).to eq "myparser_"
|
expect(grammar.prefix).to eq "myparser_"
|
||||||
|
|
||||||
o = grammar.tokens.find {|token| token.name == "code1"}
|
o = grammar.tokens.find {|token| token.name == "code1"}
|
||||||
@@ -122,7 +122,7 @@ EOF
|
|||||||
|
|
||||||
o = grammar.patterns.find {|pattern| pattern.token == o}
|
o = grammar.patterns.find {|pattern| pattern.token == o}
|
||||||
expect(o).to_not be_nil
|
expect(o).to_not be_nil
|
||||||
expect(o.code).to eq " a = b;\n return c;\n"
|
expect(o.code).to eq %[#line 2 "test.propane"\n a = b;\n return c;\n#linereset\n]
|
||||||
|
|
||||||
o = grammar.tokens.find {|token| token.name == "code2"}
|
o = grammar.tokens.find {|token| token.name == "code2"}
|
||||||
expect(o).to_not be_nil
|
expect(o).to_not be_nil
|
||||||
@@ -130,7 +130,7 @@ EOF
|
|||||||
|
|
||||||
o = grammar.patterns.find {|pattern| pattern.token == o}
|
o = grammar.patterns.find {|pattern| pattern.token == o}
|
||||||
expect(o).to_not be_nil
|
expect(o).to_not be_nil
|
||||||
expect(o.code).to eq %[ writeln("Hello there");\n]
|
expect(o.code).to eq %[#line 7 "test.propane"\n writeln("Hello there");\n#linereset\n]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "supports mode labels" do
|
it "supports mode labels" do
|
||||||
@@ -144,7 +144,7 @@ m2: /bar/ <<
|
|||||||
drop /q/;
|
drop /q/;
|
||||||
m3: drop /r/;
|
m3: drop /r/;
|
||||||
EOF
|
EOF
|
||||||
grammar = Grammar.new(input)
|
grammar = Grammar.new(input, "test.propane")
|
||||||
|
|
||||||
o = grammar.tokens.find {|token| token.name == "a"}
|
o = grammar.tokens.find {|token| token.name == "a"}
|
||||||
expect(o).to_not be_nil
|
expect(o).to_not be_nil
|
||||||
@@ -197,7 +197,7 @@ tokenid int(integer);
|
|||||||
Start (node) -> R;
|
Start (node) -> R;
|
||||||
R -> abc int;
|
R -> abc int;
|
||||||
EOF
|
EOF
|
||||||
grammar = Grammar.new(input)
|
grammar = Grammar.new(input, "test.propane")
|
||||||
|
|
||||||
o = grammar.tokens.find {|token| token.name == "abc"}
|
o = grammar.tokens.find {|token| token.name == "abc"}
|
||||||
expect(o).to_not be_nil
|
expect(o).to_not be_nil
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class TestLexer
|
|||||||
end
|
end
|
||||||
|
|
||||||
def run(grammar, input)
|
def run(grammar, input)
|
||||||
grammar = Propane::Grammar.new(grammar)
|
grammar = Propane::Grammar.new(grammar, "test.propane")
|
||||||
token_dfa = Propane::Lexer::DFA.new(grammar.patterns)
|
token_dfa = Propane::Lexer::DFA.new(grammar.patterns)
|
||||||
test_lexer = TestLexer.new(token_dfa)
|
test_lexer = TestLexer.new(token_dfa)
|
||||||
test_lexer.lex(input)
|
test_lexer.lex(input)
|
||||||
|
|||||||
Reference in new issue
Block a user