packcr 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []