From f2347a3d84a5c70f1de9b701ef5ebd8ff54ccd62 Mon Sep 17 00:00:00 2001 From: Ryan Davis Date: Tue, 18 Jul 2023 20:17:43 -0700 Subject: [PATCH] Add --frozen to add frozen_string_literals to top of generated files. --- bin/racc | 5 + doc/ja/command.ja.html | 5 + lib/racc/parser.rb | 2 + lib/racc/parserfilegenerator.rb | 3 + test/assets/frozen.y | 47 +++++++ test/regress/frozen | 225 ++++++++++++++++++++++++++++++++ test/test_racc_command.rb | 8 ++ 7 files changed, 295 insertions(+) create mode 100644 test/assets/frozen.y create mode 100644 test/regress/frozen diff --git a/bin/racc b/bin/racc index 4507d049..5c6b046b 100755 --- a/bin/racc +++ b/bin/racc @@ -19,6 +19,7 @@ def main make_executable = false rubypath = nil embed_runtime = false + frozen_strings = false debug_flags = Racc::DebugFlags.new line_convert = true line_convert_all = false @@ -57,6 +58,9 @@ def main parser.on('-E', '--embedded', "Embeds Racc runtime in output.") { embed_runtime = true } + parser.on('-F', '--frozen', "Add frozen_string_literals: true.") { + frozen_strings = true + } parser.on('--line-convert-all', 'Converts line numbers of user codes.') { line_convert_all = true } @@ -162,6 +166,7 @@ def main params.convert_line = line_convert params.convert_line_all = line_convert_all params.embed_runtime = embed_runtime + params.frozen_strings = frozen_strings profiler.section('generation') { generator = Racc::ParserFileGenerator.new(states, params) generator.generate_parser_file(output || make_filename(input, '.tab.rb')) diff --git a/doc/ja/command.ja.html b/doc/ja/command.ja.html index f7223076..52eccfd4 100644 --- a/doc/ja/command.ja.html +++ b/doc/ja/command.ja.html @@ -6,6 +6,7 @@

Raccコマンドリファレンス

[-Ofilename] [--log-file=filename] [-g] [--debug] [-E] [--embedded] + [-F] [--frozen] [-l] [--no-line-convert] [-c] [--line-convert-all] [-a] [--no-omit-actions] @@ -50,6 +51,10 @@

Raccコマンドリファレンス

ランタイムルーチンをすべて含んだコードを生成します。 つまり、このオプションをつけて生成したコードは Ruby さえあれば動きます。 +
-F, --frozen +
+Add frozen_string_literals: true. +
-C, --check-only
(文法ファイルの) 文法のチェックだけをして終了します。 diff --git a/lib/racc/parser.rb b/lib/racc/parser.rb index 9ad8f104..20f04fb6 100644 --- a/lib/racc/parser.rb +++ b/lib/racc/parser.rb @@ -57,6 +57,8 @@ class ParseError < StandardError; end # use this '-g' option and set @yydebug true in parser class. # [-E, --embedded] # Output parser which doesn't need runtime files (racc/parser.rb). +# [-F, --frozen] +# Output parser which declares frozen_string_literals: true # [-C, --check-only] # Check syntax of racc grammar file and quit. # [-S, --output-status] diff --git a/lib/racc/parserfilegenerator.rb b/lib/racc/parserfilegenerator.rb index 236ff27d..e6ea53d1 100644 --- a/lib/racc/parserfilegenerator.rb +++ b/lib/racc/parserfilegenerator.rb @@ -45,6 +45,7 @@ def #{name}=(b) bool_attr :convert_line bool_attr :convert_line_all bool_attr :embed_runtime + bool_attr :frozen_strings bool_attr :make_executable attr_accessor :interpreter @@ -64,6 +65,7 @@ def initialize self.convert_line = true self.convert_line_all = false self.embed_runtime = false + self.frozen_strings = false self.make_executable = false self.interpreter = nil end @@ -122,6 +124,7 @@ def shebang(path) end def notice + line %q[# frozen_string_literal: true] if @params.frozen_strings? line %q[#] line %q[# DO NOT MODIFY!!!!] line %Q[# This file is automatically generated by Racc #{Racc::Version}] diff --git a/test/assets/frozen.y b/test/assets/frozen.y new file mode 100644 index 00000000..c2640f33 --- /dev/null +++ b/test/assets/frozen.y @@ -0,0 +1,47 @@ +class Journey::Parser + +token SLASH LITERAL SYMBOL LPAREN RPAREN DOT STAR OR + +rule + expressions + : expressions expression { result = Cat.new(val.first, val.last) } + | expression { result = val.first } + | or + ; + expression + : terminal + | group + | star + ; + group + : LPAREN expressions RPAREN { result = Group.new(val[1]) } + ; + or + : expressions OR expression { result = Or.new([val.first, val.last]) } + ; + star + : STAR { result = Star.new(Symbol.new(val.last)) } + ; + terminal + : symbol + | literal + | slash + | dot + ; + slash + : SLASH { result = Slash.new('/') } + ; + symbol + : SYMBOL { result = Symbol.new(val.first) } + ; + literal + : LITERAL { result = Literal.new(val.first) } + dot + : DOT { result = Dot.new(val.first) } + ; + +end + +---- header + +require 'journey/parser_extras' diff --git a/test/regress/frozen b/test/regress/frozen new file mode 100644 index 00000000..b8d69c82 --- /dev/null +++ b/test/regress/frozen @@ -0,0 +1,225 @@ +# frozen_string_literal: true +# +# DO NOT MODIFY!!!! +# This file is automatically generated by Racc 1.5.2 +# from Racc grammar file "". +# + +require 'racc/parser.rb' + + +require 'journey/parser_extras' +module Journey + class Parser < Racc::Parser +##### State transition tables begin ### + +racc_action_table = [ + 17, 21, 13, 15, 14, 7, nil, 16, 8, 19, + 13, 15, 14, 7, 23, 16, 8, 19, 13, 15, + 14, 7, nil, 16, 8, 13, 15, 14, 7, nil, + 16, 8, 13, 15, 14, 7, nil, 16, 8 ] + +racc_action_check = [ + 1, 17, 1, 1, 1, 1, nil, 1, 1, 1, + 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, + 0, 0, nil, 0, 0, 7, 7, 7, 7, nil, + 7, 7, 19, 19, 19, 19, nil, 19, 19 ] + +racc_action_pointer = [ + 16, 0, nil, nil, nil, nil, nil, 23, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 1, nil, 30, + 8, nil, nil, nil ] + +racc_action_default = [ + -18, -18, -2, -3, -4, -5, -6, -18, -9, -10, + -11, -12, -13, -14, -15, -16, -17, -18, -1, -18, + -18, 24, -8, -7 ] + +racc_goto_table = [ + 18, 1, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 22, 18 ] + +racc_goto_check = [ + 2, 1, nil, nil, nil, nil, nil, nil, 1, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 2, 2 ] + +racc_goto_pointer = [ + nil, 1, -1, nil, nil, nil, nil, nil, nil, nil, + nil ] + +racc_goto_default = [ + nil, nil, 2, 3, 4, 5, 6, 9, 10, 11, + 12 ] + +racc_reduce_table = [ + 0, 0, :racc_error, + 2, 11, :_reduce_1, + 1, 11, :_reduce_2, + 1, 11, :_reduce_none, + 1, 12, :_reduce_none, + 1, 12, :_reduce_none, + 1, 12, :_reduce_none, + 3, 15, :_reduce_7, + 3, 13, :_reduce_8, + 1, 16, :_reduce_9, + 1, 14, :_reduce_none, + 1, 14, :_reduce_none, + 1, 14, :_reduce_none, + 1, 14, :_reduce_none, + 1, 19, :_reduce_14, + 1, 17, :_reduce_15, + 1, 18, :_reduce_16, + 1, 20, :_reduce_17 ] + +racc_reduce_n = 18 + +racc_shift_n = 24 + +racc_token_table = { + false => 0, + :error => 1, + :SLASH => 2, + :LITERAL => 3, + :SYMBOL => 4, + :LPAREN => 5, + :RPAREN => 6, + :DOT => 7, + :STAR => 8, + :OR => 9 } + +racc_nt_base = 10 + +racc_use_result_var = true + +Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] +Ractor.make_shareable(Racc_arg) if defined?(Ractor) + +Racc_token_to_s_table = [ + "$end", + "error", + "SLASH", + "LITERAL", + "SYMBOL", + "LPAREN", + "RPAREN", + "DOT", + "STAR", + "OR", + "$start", + "expressions", + "expression", + "or", + "terminal", + "group", + "star", + "symbol", + "literal", + "slash", + "dot" ] +Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) + +Racc_debug_parser = false + +##### State transition tables end ##### + +# reduce 0 omitted + +module_eval(<<'.,.,', 'frozen.y', 6) + def _reduce_1(val, _values, result) + result = Cat.new(val.first, val.last) + result + end +.,., + +module_eval(<<'.,.,', 'frozen.y', 7) + def _reduce_2(val, _values, result) + result = val.first + result + end +.,., + +# reduce 3 omitted + +# reduce 4 omitted + +# reduce 5 omitted + +# reduce 6 omitted + +module_eval(<<'.,.,', 'frozen.y', 16) + def _reduce_7(val, _values, result) + result = Group.new(val[1]) + result + end +.,., + +module_eval(<<'.,.,', 'frozen.y', 19) + def _reduce_8(val, _values, result) + result = Or.new([val.first, val.last]) + result + end +.,., + +module_eval(<<'.,.,', 'frozen.y', 22) + def _reduce_9(val, _values, result) + result = Star.new(Symbol.new(val.last)) + result + end +.,., + +# reduce 10 omitted + +# reduce 11 omitted + +# reduce 12 omitted + +# reduce 13 omitted + +module_eval(<<'.,.,', 'frozen.y', 31) + def _reduce_14(val, _values, result) + result = Slash.new('/') + result + end +.,., + +module_eval(<<'.,.,', 'frozen.y', 34) + def _reduce_15(val, _values, result) + result = Symbol.new(val.first) + result + end +.,., + +module_eval(<<'.,.,', 'frozen.y', 37) + def _reduce_16(val, _values, result) + result = Literal.new(val.first) + result + end +.,., + +module_eval(<<'.,.,', 'frozen.y', 39) + def _reduce_17(val, _values, result) + result = Dot.new(val.first) + result + end +.,., + +def _reduce_none(val, _values, result) + val[0] +end + + end # class Parser +end # module Journey diff --git a/test/test_racc_command.rb b/test/test_racc_command.rb index 9d2b566b..f8f3856e 100644 --- a/test/test_racc_command.rb +++ b/test/test_racc_command.rb @@ -199,6 +199,14 @@ def test_journey assert_output_unchanged 'journey.y' end + # .y file from journey gem, but with --frozen + + def test_frozen + assert_compile 'frozen.y', '--frozen' + assert_debugfile 'frozen.y', [] + assert_output_unchanged 'frozen.y' + end + # .y file from nokogiri gem def test_nokogiri_css