packcr 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,101 @@
1
+ require "securerandom"
2
+
3
+ class Packcr
4
+ class Stream
5
+ def initialize(io, name, line)
6
+ @io = io
7
+ @name = name
8
+ @line = line
9
+ @line_directive_tag = nil
10
+ end
11
+
12
+ def write(s, rewrite_line_directive: false)
13
+ if rewrite_line_directive && @line_directive_tag && @line.respond_to?(:+)
14
+ s.gsub!(@line_directive_tag) { (@line + $`.count("\n") + 1).to_s }
15
+ @line_directive_tag = nil
16
+ end
17
+ @io.write(s)
18
+ if @line.respond_to?(:+)
19
+ @line += s.count("\n")
20
+ end
21
+ end
22
+
23
+ def write_text(s)
24
+ write s.gsub(/\r\n/, "\n")
25
+ end
26
+
27
+ def write_line_directive(fname, lineno)
28
+ return unless @line
29
+ if lineno.respond_to?(:+)
30
+ write("#line #{lineno + 1} \"")
31
+ else
32
+ @line_directive_tag ||= "<#{SecureRandom.uuid}>"
33
+ write("#line #{@line_directive_tag} \"")
34
+ end
35
+
36
+ write(Packcr.escape_string(fname))
37
+ write("\"\n")
38
+ end
39
+
40
+ def write_output_line_directive
41
+ write_line_directive(@name, @line)
42
+ end
43
+
44
+ def write_code_block(code, indent, fname)
45
+ text = code.text
46
+ ptr = text.b
47
+ len = code.len
48
+ lineno = code.line
49
+ if len == nil
50
+ return # for safety
51
+ end
52
+
53
+ ptr.sub!(/\A\n+/) do
54
+ lineno += $&.length
55
+ ""
56
+ end
57
+ ptr.sub!(/[ \v\f\t\r\n]*\z/, "")
58
+
59
+ min_indent_spaces = nil
60
+ ptr.gsub!(/^([ \v\f\t]+)([^ \v\f\t\r\n])/) do
61
+ spaces = $1
62
+ char = $2
63
+
64
+ next char if char == "#"
65
+
66
+ Packcr.unify_indent_spaces(spaces)
67
+
68
+ if !min_indent_spaces || min_indent_spaces.length > spaces.length
69
+ min_indent_spaces = spaces
70
+ end
71
+
72
+ spaces + char
73
+ end
74
+
75
+ if min_indent_spaces
76
+ indent_spaces = " " * indent
77
+ ptr.gsub!(/^#{min_indent_spaces}( *[^\n#])/) do
78
+ "#{indent_spaces}#{$1}"
79
+ end
80
+ end
81
+
82
+ return if ptr.empty?
83
+
84
+ write_line_directive(fname, lineno)
85
+ ptr.scan(/^(.+?)[ \v\f\t\r]*$|^\r?\n/) do
86
+ write $1 if $1
87
+ write "\n"
88
+ end
89
+ write_output_line_directive
90
+ end
91
+
92
+ def get_code_block(code, indent, fname)
93
+ buf = StringIO.new
94
+ line, io, @io, @line = @line, @io, buf, @line && :uuid
95
+ write_code_block(code, indent, fname)
96
+ return buf.string
97
+ ensure
98
+ @line, @io = line, io
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,94 @@
1
+ class Packcr
2
+ module Util
3
+ def is_identifier_string(str)
4
+ str.match?(/\A(?!\d)\w+\z/)
5
+ end
6
+
7
+ def unescape_string(str, is_charclass)
8
+ if is_charclass
9
+ str.gsub!("\\" * 2) { "\\" * 4 }
10
+ end
11
+ str.gsub!(/\\(.)/) do
12
+ c = $1
13
+ case c
14
+ when "0"
15
+ "\\x00"
16
+ when "'"
17
+ c
18
+ else
19
+ "\\#{c}"
20
+ end
21
+ end
22
+ str.gsub!(/[^\x00-\x7f]/) do
23
+ "\\x%02x" % $&.ord
24
+ end
25
+ str.replace "\"#{str}\"".undump
26
+ end
27
+
28
+ def escape_character(c)
29
+ escape_string(c.chr)
30
+ end
31
+
32
+ def escape_string(str)
33
+ str = str.b
34
+ str.gsub(/(\0+)|(\e+)|("+)|('+)|(\\+)|((?:(?![\0\e"'\\])[ -~])+)|([\x01-\x1a\x1c-\x1f\x7f-\xff]+)/n) do
35
+ n = $&.size
36
+ next "\\0" * n if $1
37
+ next "\\x1b" * n if $2
38
+ next "\\\"" * n if $3
39
+ next "\\\'" * n if $4
40
+ next "\\\\" * n if $5
41
+ next $6 if $6
42
+ $7.dump[1..-2].downcase
43
+ end
44
+ end
45
+
46
+ def dump_integer_value(value)
47
+ if value == nil
48
+ $stdout.print "void"
49
+ else
50
+ $stdout.print value
51
+ end
52
+ end
53
+
54
+ def dump_escaped_string(str)
55
+ if !str
56
+ $stdout.print "null"
57
+ return
58
+ end
59
+ $stdout.print escape_string(str)
60
+ end
61
+
62
+ def find_trailing_blanks(str)
63
+ str =~ /[ \v\f\t\n\r]*\z/
64
+ end
65
+
66
+ def unify_indent_spaces(spaces)
67
+ offset = 0
68
+ spaces.tr!("\v\f", " ")
69
+ spaces.gsub!(/\t+/) do
70
+ chars = $`.length
71
+ o = 8 * $&.length - (offset + chars) % 8
72
+ offset = (7 - chars) % 8
73
+ " " * o
74
+ end
75
+ spaces
76
+ end
77
+
78
+ def template(path, b, indent: 0, unwrap: false)
79
+ template_path = File.join(File.dirname(__FILE__), "templates", path)
80
+ erb = ERB.new(File.read(template_path), trim_mode: "%-")
81
+ erb.filename = template_path
82
+ result = erb.result(b)
83
+ if unwrap
84
+ result.gsub!(/\A\{|\}\z/, "")
85
+ indent -= 4
86
+ end
87
+ result.gsub!(/^(?!$)/, " " * indent)
88
+ result.gsub!(/^( *?) {0,4}<<<</) { $1 }
89
+ result
90
+ end
91
+ end
92
+
93
+ extend Util
94
+ end
@@ -0,0 +1,3 @@
1
+ class Packcr
2
+ VERSION = "0.0.3"
3
+ end
data/lib/packcr.rb ADDED
@@ -0,0 +1,33 @@
1
+ class Packcr
2
+ end
3
+
4
+ require "packcr/util"
5
+ require "packcr/code_block"
6
+ require "packcr/stream"
7
+ require "packcr/generator"
8
+ require "packcr/buffer"
9
+ require "packcr/node"
10
+ require "packcr/context"
11
+ require "packcr/version"
12
+
13
+ class Packcr
14
+ CODE_REACH__BOTH = 0
15
+ CODE_REACH__ALWAYS_SUCCEED = 1
16
+ CODE_REACH__ALWAYS_FAIL = -1
17
+
18
+ def initialize(path, **opt)
19
+ @path = path.to_s
20
+ @opt = opt
21
+ end
22
+
23
+ def run
24
+ Context.new(@path.to_s, **@opt) do |ctx|
25
+ if !ctx.parse
26
+ raise "PackCR error: can't parse"
27
+ end
28
+ if !ctx.generate
29
+ raise "PackCR error: can't generate"
30
+ end
31
+ end
32
+ end
33
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: packcr
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - wanabe
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-01-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: test-unit
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.5'
27
+ description:
28
+ email:
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - lib/packcr.rb
34
+ - lib/packcr/buffer.rb
35
+ - lib/packcr/code_block.rb
36
+ - lib/packcr/context.rb
37
+ - lib/packcr/generator.rb
38
+ - lib/packcr/node.rb
39
+ - lib/packcr/node/action_node.rb
40
+ - lib/packcr/node/alternate_node.rb
41
+ - lib/packcr/node/capture_node.rb
42
+ - lib/packcr/node/charclass_node.rb
43
+ - lib/packcr/node/error_node.rb
44
+ - lib/packcr/node/expand_node.rb
45
+ - lib/packcr/node/predicate_node.rb
46
+ - lib/packcr/node/quantity_node.rb
47
+ - lib/packcr/node/reference_node.rb
48
+ - lib/packcr/node/rule_node.rb
49
+ - lib/packcr/node/sequence_node.rb
50
+ - lib/packcr/node/string_node.rb
51
+ - lib/packcr/stream.rb
52
+ - lib/packcr/util.rb
53
+ - lib/packcr/version.rb
54
+ homepage: https://github.com/wanabe/packcr
55
+ licenses:
56
+ - MIT
57
+ metadata: {}
58
+ post_install_message:
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubygems_version: 3.4.1
74
+ signing_key:
75
+ specification_version: 4
76
+ summary: Parser generator for C or Ruby
77
+ test_files: []