Skip to content

Commit

Permalink
Support expect! declaration in Racc grammar file
Browse files Browse the repository at this point in the history
`expect` warns the difference between expected S/R conflicts count
and actual count however racc command exits with success.
racc command will exit with failure if `expect!` declaration
is specified therefore build process of racc user will also fail.
  • Loading branch information
yui-knk committed Apr 30, 2024
1 parent 0c0f585 commit 40f7b94
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 2 deletions.
3 changes: 3 additions & 0 deletions bin/racc
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,9 @@ def main
end

profiler.report
if states.should_raise_unexpected_number_of_srconflicts?
raise Racc::CompileError, "#{states.grammar.n_expected_srconflicts} shift/reduce conflicts are expected but #{states.n_srconflicts} shift/reduce conflicts exist"
end
rescue Racc::Error, Errno::ENOENT, Errno::EPERM => err
raise if $DEBUG or debug_flags.any?
lineno = err.message.slice(/\A\d+:/).to_s
Expand Down
2 changes: 2 additions & 0 deletions lib/racc/grammar.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def initialize(debug_flags = DebugFlags.new)
@rules = [] # :: [Rule]
@start = nil
@n_expected_srconflicts = nil
@raise_unexpected_number_of_srconflicts = nil
@prec_table = []
@prec_table_closed = false
@closed = false
Expand All @@ -36,6 +37,7 @@ def initialize(debug_flags = DebugFlags.new)
attr_reader :start
attr_reader :symboltable
attr_accessor :n_expected_srconflicts
attr_accessor :raise_unexpected_number_of_srconflicts

def [](x)
@rules[x]
Expand Down
13 changes: 11 additions & 2 deletions lib/racc/grammarfileparser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,17 @@ module Racc
}\
| seq(:EXPECT, :DIGIT) {|_, num|
if @grammar.n_expected_srconflicts
raise CompileError, "`expect' seen twice"
raise CompileError, "`expect and/or expect!' seen twice"
end
@grammar.n_expected_srconflicts = num
@grammar.raise_unexpected_number_of_srconflicts = false
}\
| seq(:EXPECT!, :DIGIT) {|_, num|
if @grammar.n_expected_srconflicts
raise CompileError, "`expect and/or expect!' seen twice"
end
@grammar.n_expected_srconflicts = num
@grammar.raise_unexpected_number_of_srconflicts = true
}

g.convdef = seq(:symbol, :STRING) {|sym, code|
Expand Down Expand Up @@ -439,7 +447,7 @@ def yylex0
break
elsif /\A\/\*/ =~ @line
skip_comment
elsif s = reads(/\A[a-zA-Z_]\w*/)
elsif s = reads(/\A[a-zA-Z_]\w*!?/)
yield [atom_symbol(s), s.intern]
elsif s = reads(/\A\d+/)
yield [:DIGIT, s.to_i]
Expand Down Expand Up @@ -493,6 +501,7 @@ def next_line
'options' => :OPTION,
'start' => :START,
'expect' => :EXPECT,
'expect!' => :EXPECT!,
'class' => :CLASS,
'rule' => :RULE,
'end' => :END
Expand Down
4 changes: 4 additions & 0 deletions lib/racc/state.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ def should_report_srconflict?
(n_srconflicts() != @grammar.n_expected_srconflicts)
end

def should_raise_unexpected_number_of_srconflicts?
should_report_srconflict? && @grammar.raise_unexpected_number_of_srconflicts
end

def srconflict_exist?
n_srconflicts() != 0
end
Expand Down
7 changes: 7 additions & 0 deletions test/assets/expect_bang.y
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class E
expect! 0
rule
list: inlist inlist
inlist:
| A
end
7 changes: 7 additions & 0 deletions test/test_racc_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,13 @@ def test_expect_y
assert_debugfile 'expect.y', [1,0,0,0,1]
end

def test_expect_bang_y
assert_raise_with_message(Test::Unit::AssertionFailedError, /0 shift\/reduce conflicts are expected but 1 shift\/reduce conflicts exist/) {
assert_compile 'expect_bang.y'
}
assert_debugfile 'expect_bang.y', [1,0,0,0,0]
end

def test_nullbug1_y
assert_compile 'nullbug1.y'
assert_debugfile 'nullbug1.y', [0,0,0,0]
Expand Down

0 comments on commit 40f7b94

Please sign in to comment.