Class: LexerKit::Format::LKT1
- Inherits:
-
Object
- Object
- LexerKit::Format::LKT1
- Defined in:
- lib/lexer_kit/format/lkt1.rb
Overview
LKT1 (LexerKit Text format version 1) is a JSON-based container format for compiled lexer programs. It supports compression and includes integrity checking via SHA256.
Instance Attribute Summary collapse
-
#program ⇒ Object
readonly
Returns the value of attribute program.
Class Method Summary collapse
-
.decode(json_string) ⇒ LKT1
Decode a compiled lexer program from lkt1 JSON string.
-
.load(path) ⇒ LKT1
Load a compiled lexer program from a .lkt1 file.
-
.save(program, path:) ⇒ Object
Save a compiled lexer program to a .lkt1 file (shortcut).
Instance Method Summary collapse
-
#encode ⇒ String
Encode the program to lkt1 JSON string.
-
#initialize(program) ⇒ LKT1
constructor
Create a new LKT1 instance from a compiled program.
-
#save(path) ⇒ Object
Save the program to a .lkt1 file.
Constructor Details
#initialize(program) ⇒ LKT1
Create a new LKT1 instance from a compiled program
18 19 20 |
# File 'lib/lexer_kit/format/lkt1.rb', line 18 def initialize(program) @program = program end |
Instance Attribute Details
#program ⇒ Object (readonly)
Returns the value of attribute program.
14 15 16 |
# File 'lib/lexer_kit/format/lkt1.rb', line 14 def program @program end |
Class Method Details
.decode(json_string) ⇒ LKT1
Decode a compiled lexer program from lkt1 JSON string
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/lexer_kit/format/lkt1.rb', line 40 def self.decode(json_string) container = JSON.parse(json_string, symbolize_names: true) # Validate format unless container[:format] == "lkt1" raise LexerKit::IntegrityError, "Unknown format: #{container[:format]}" end unless container[:kind] == "program" raise LexerKit::IntegrityError, "Unknown kind: #{container[:kind]}" end # Decode based on codec unless container[:codec] == "deflate+base64" raise LexerKit::IntegrityError, "Unknown codec: #{container[:codec]}" end compressed = Base64.strict_decode64(container[:data]) binary = Zlib::Inflate.inflate(compressed) # Verify integrity (sha256 is required) unless container[:sha256] raise LexerKit::IntegrityError, "Missing required field: sha256" end actual_hash = Digest::SHA256.hexdigest(binary) unless actual_hash == container[:sha256] raise LexerKit::IntegrityError, "SHA256 mismatch: expected #{container[:sha256]}, got #{actual_hash}" end if container[:uncompressed_len] && binary.bytesize != container[:uncompressed_len] raise LexerKit::IntegrityError, "Length mismatch: expected #{container[:uncompressed_len]}, got #{binary.bytesize}" end program = IR::CompiledProgram.from_binary(binary) program.load_native! if LexerKit.native? new(program) rescue JSON::ParserError => e raise LexerKit::IntegrityError, "Invalid JSON: #{e.}" rescue ArgumentError => e # Base64 decode errors raise LexerKit::IntegrityError, "Decoding error: #{e.}" rescue Zlib::Error => e raise LexerKit::IntegrityError, "Decompression error: #{e.}" end |
.load(path) ⇒ LKT1
Load a compiled lexer program from a .lkt1 file
25 26 27 28 |
# File 'lib/lexer_kit/format/lkt1.rb', line 25 def self.load(path) content = File.read(path) decode(content) end |
.save(program, path:) ⇒ Object
Save a compiled lexer program to a .lkt1 file (shortcut)
33 34 35 |
# File 'lib/lexer_kit/format/lkt1.rb', line 33 def self.save(program, path:) new(program).save(path) end |
Instance Method Details
#encode ⇒ String
Encode the program to lkt1 JSON string
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/lexer_kit/format/lkt1.rb', line 88 def encode binary = @program.to_binary compressed = Zlib::Deflate.deflate(binary) encoded = Base64.strict_encode64(compressed) JSON.generate({ format: "lkt1", codec: "deflate+base64", kind: "program", table_version: 2, uncompressed_len: binary.bytesize, sha256: Digest::SHA256.hexdigest(binary), data: encoded }) end |
#save(path) ⇒ Object
Save the program to a .lkt1 file
106 107 108 |
# File 'lib/lexer_kit/format/lkt1.rb', line 106 def save(path) File.write(path, encode) end |