lrama 0.5.6 → 0.5.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e54c51af6f1d3632293cbd7f68762bf7cff63758d3ce633113805a629b92072b
4
- data.tar.gz: 5d053543f0e00c9fb20c40f5ca8236e499292f35fa8cf6fb8e85cac33b930814
3
+ metadata.gz: c786e8955350ca51e6226aacd493073f7c31714ef7d5911dfb16259aa9415513
4
+ data.tar.gz: d167b1a2df9dcbc8f31912e8842388aa7d6a788a8d3eeff0278c6d3ed5ecbac6
5
5
  SHA512:
6
- metadata.gz: 87bafe9650720b154855e055e53d700cfba67d31489dbc855c716bc150dff35e92d0fc974c14cb81a07ae68febbd69118c1720a628e2819fec1ebfa304acad55
7
- data.tar.gz: 19b0c51748cef053d205bbf13e8ff238bda2fdbb101d304f6bfe9633b4f88fe2c4a1f452627528fd2c9e78bc97955a2a5f7543212aa581c3a9f7ae96dd3d70f8
6
+ metadata.gz: c89fe932ef32b5f441b87df33c2431c8631a069c293306d0a39c858e462731e11d753117ab4e7c48b4e4e41015405328a8d8f5590fbce3544e67babdaeddd8a6
7
+ data.tar.gz: 619d1affd9f09c5c1b7748f712005b60073638be709e8bae986e39801173cf9de32555cf05837dbb7450360989989f5277e76a496eec702ace75c3b4af944471
data/.codespellignore ADDED
File without changes
@@ -0,0 +1,16 @@
1
+ name: CodeSpell
2
+ on:
3
+ - pull_request
4
+ jobs:
5
+ codespell:
6
+ name: CodeSpell
7
+ runs-on: ubuntu-latest
8
+ steps:
9
+ - uses: actions/checkout@v4
10
+ - name: CodeSpell
11
+ uses: codespell-project/actions-codespell@master
12
+ with:
13
+ check_filenames: true
14
+ check_hidden: true
15
+ ignore_words_file: .codespellignore
16
+ exclude_file: lib/lrama/parser.rb
@@ -38,13 +38,27 @@ jobs:
38
38
  - run: bundle exec rspec
39
39
  check-misc:
40
40
  runs-on: ubuntu-20.04
41
+ strategy:
42
+ matrix:
43
+ ruby: ['head']
41
44
  steps:
42
45
  - uses: actions/checkout@v4
46
+ - uses: ruby/setup-ruby@v1
47
+ with:
48
+ ruby-version: ${{ matrix.ruby }}
49
+ bundler-cache: true
50
+ - run: bundle install
51
+
43
52
  # Copy from https://github.com/ruby/ruby/blob/089227e94823542acfdafa68541d330eee42ffea/.github/workflows/check_misc.yml#L27
44
53
  - name: Check for trailing spaces
45
54
  run: |
46
- git grep -I -n '[ ]$' -- '*.rb' '*.[chy]' '*.rs' && exit 1 || :
55
+ git grep -I -n '[ ]$' -- '*.rb' '*.[chy]' '*.rs' ':!spec/' && exit 1 || :
47
56
  git grep -n '^[ ][ ]*$' -- '*.md' && exit 1 || :
57
+
58
+ - name: Check for parser.rb is up to date
59
+ run: |
60
+ bundle exec rake build:racc_parser
61
+ git diff --color --no-ext-diff --ignore-submodules --exit-code lib/lrama/parser.rb
48
62
  steep-check:
49
63
  runs-on: ubuntu-20.04
50
64
  strategy:
@@ -65,7 +79,9 @@ jobs:
65
79
  strategy:
66
80
  fail-fast: false
67
81
  matrix:
68
- baseruby: ['3.0']
82
+ # '3.0' is the oldest living ruby version
83
+ # '2.5' is for BASERUBY
84
+ baseruby: ['head', '3.0', '2.5']
69
85
  ruby_branch: ['master']
70
86
  defaults:
71
87
  run:
data/.gitignore CHANGED
@@ -4,3 +4,4 @@
4
4
  /Gemfile.lock
5
5
  /pkg/
6
6
  coverage/
7
+ /parser.output
data/Gemfile CHANGED
@@ -6,6 +6,7 @@ gem "rspec"
6
6
  gem "pry"
7
7
  # stackprof doesn't support Windows
8
8
  gem "stackprof", platforms: [:ruby]
9
+ gem "racc"
9
10
  gem "rake"
10
11
  gem "rbs", require: false
11
12
  gem "steep", require: false
data/README.md CHANGED
@@ -61,12 +61,78 @@ This branch generates "parse.c" compatible with Bison 3.8.2 for ruby 3.0, 3.1, 3
61
61
 
62
62
  Lrama is executed with BASERUBY when building ruby from source code. Therefore Lrama needs to support BASERUBY, currently 2.5, or later version.
63
63
 
64
- This also requires Lrama to be able to run with only default gems and bundled gems.
64
+ This also requires Lrama to be able to run with only default gems because BASERUBY runs with `--disable=gems` option.
65
65
 
66
- ## Build Ruby
66
+ ## Development
67
+
68
+ ### How to generate new_parser.rb
69
+
70
+ ```shell
71
+ $ rake build:racc_parser
72
+ ```
73
+
74
+ `new_parser.rb` is generated from `parser.y` by Racc.
75
+ Run the rake command when you update `parser.y` then commit changes of both files.
76
+
77
+ ### Test
78
+
79
+ Running tests:
80
+
81
+ ```shell
82
+ $ bundle install
83
+ $ bundle exec rspec
84
+ ```
85
+
86
+ Running type check:
87
+
88
+ ```shell
89
+ $ bundle install
90
+ $ bundle exec rbs collection install
91
+ $ bundle exec steep check
92
+ ```
93
+
94
+ ### Profiling Lrama
95
+
96
+ #### 1. Create parse.tmp.y in ruby/ruby
97
+
98
+ ```shell
99
+ $ ruby tool/id2token.rb parse.y > parse.tmp.y
100
+ $ cp parse.tmp.y dir/lrama/tmp
101
+ ```
102
+
103
+ #### 2. Enable Profiler
104
+
105
+ ```diff
106
+ diff --git a/exe/lrama b/exe/lrama
107
+ index ba5fb06..2497178 100755
108
+ --- a/exe/lrama
109
+ +++ b/exe/lrama
110
+ @@ -3,4 +3,6 @@
111
+ $LOAD_PATH << File.join(__dir__, "../lib")
112
+ require "lrama"
113
+
114
+ -Lrama::Command.new.run(ARGV.dup)
115
+ +Lrama::Report::Profile.report_profile do
116
+ + Lrama::Command.new.run(ARGV.dup)
117
+ +end
118
+ ```
119
+
120
+ #### 3. Run Lrama
121
+
122
+ ```shell
123
+ $ exe/lrama -o parse.tmp.c --header=parse.tmp.h tmp/parse.tmp.y
124
+ ```
125
+
126
+ #### 4. Generate Flamegraph
127
+
128
+ ```shell
129
+ $ stackprof --d3-flamegraph tmp/stackprof-cpu-myapp.dump > tmp/flamegraph.html
130
+ ```
131
+
132
+ ### Build Ruby
67
133
 
68
134
  1. Install Lrama
69
- 2. Run `make YACC=lrama`
135
+ 2. Run `make main`
70
136
 
71
137
  ## Release flow
72
138
 
data/Rakefile CHANGED
@@ -1 +1,13 @@
1
1
  require "bundler/gem_tasks"
2
+
3
+ namespace "build" do
4
+ desc "build parser from parser.y by using Racc"
5
+ task :racc_parser do
6
+ `bundle exec racc parser.y --embedded -o lib/lrama/parser.rb`
7
+ end
8
+
9
+ desc "build parser for debugging"
10
+ task :racc_verbose_parser do
11
+ `bundle exec racc parser.y --embedded -o lib/lrama/parser.rb -t --log-file=parser.output`
12
+ end
13
+ end
data/Steepfile CHANGED
@@ -1,10 +1,13 @@
1
1
  # D = Steep::Diagnostic
2
2
  #
3
3
  target :lib do
4
+ repo_path '.gem_rbs_collection/'
4
5
  signature "sig"
5
6
 
6
7
  check "lib/lrama/bitmap.rb"
8
+ check "lib/lrama/digraph.rb"
7
9
  check "lib/lrama/report/duration.rb"
8
10
  check "lib/lrama/report/profile.rb"
11
+ check "lib/lrama/token/type.rb"
9
12
  check "lib/lrama/warning.rb"
10
13
  end
data/lib/lrama/command.rb CHANGED
@@ -6,8 +6,9 @@ module Lrama
6
6
  Report::Duration.enable if options.trace_opts[:time]
7
7
 
8
8
  warning = Lrama::Warning.new
9
- grammar = Lrama::Parser.new(options.y.read).parse
9
+ text = options.y.read
10
10
  options.y.close if options.y != STDIN
11
+ grammar = Lrama::Parser.new(text).parse
11
12
  states = Lrama::States.new(grammar, warning, trace_state: (options.trace_opts[:automaton] || options.trace_opts[:closure]))
12
13
  states.compute
13
14
  context = Lrama::Context.new(states)
data/lib/lrama/context.rb CHANGED
@@ -170,7 +170,7 @@ module Lrama
170
170
  return a
171
171
  end
172
172
 
173
- # Mapping from rule number to lenght of RHS.
173
+ # Mapping from rule number to length of RHS.
174
174
  # Dummy rule is appended as the first element whose value is 0
175
175
  # because 0 means error in yydefact.
176
176
  def yyr2
@@ -214,7 +214,7 @@ module Lrama
214
214
  (rule_id + 1) * -1
215
215
  end
216
216
 
217
- # Symbol number is assinged to term first then nterm.
217
+ # Symbol number is assigned to term first then nterm.
218
218
  # This method calculates sequence_number for nterm.
219
219
  def nterm_number_to_sequence_number(nterm_number)
220
220
  nterm_number - @states.terms.count
@@ -259,7 +259,7 @@ module Lrama
259
259
  actions[conflict.symbol.number] = ErrorActionNumber
260
260
  end
261
261
 
262
- # If default_reduction_rule, replase default_reduction_rule in
262
+ # If default_reduction_rule, replace default_reduction_rule in
263
263
  # actions with zero.
264
264
  if state.default_reduction_rule
265
265
  actions.map! do |e|
@@ -272,7 +272,7 @@ module Lrama
272
272
  end
273
273
 
274
274
  # If no default_reduction_rule, default behavior is an
275
- # error then replase ErrorActionNumber with zero.
275
+ # error then replace ErrorActionNumber with zero.
276
276
  if !state.default_reduction_rule
277
277
  actions.map! do |e|
278
278
  if e == ErrorActionNumber
data/lib/lrama/digraph.rb CHANGED
@@ -40,8 +40,7 @@ module Lrama
40
40
  end
41
41
 
42
42
  if @h[x] == d
43
- while true do
44
- z = @stack.pop
43
+ while (z = @stack.pop) do
45
44
  @h[z] = Float::INFINITY
46
45
  break if z == x
47
46
  @result[z] = @result[x] # F (Top of S) = F x
@@ -2,8 +2,8 @@ module Lrama
2
2
  class Grammar
3
3
  class Union < Struct.new(:code, :lineno, keyword_init: true)
4
4
  def braces_less_code
5
- # Remove braces
6
- code.s_value[1..-2]
5
+ # Braces is already removed by lexer
6
+ code.s_value
7
7
  end
8
8
  end
9
9
  end
data/lib/lrama/grammar.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require "strscan"
2
+
1
3
  require "lrama/grammar/auxiliary"
2
4
  require "lrama/grammar/code"
3
5
  require "lrama/grammar/error_token"
@@ -306,6 +308,188 @@ module Lrama
306
308
  @nterms ||= @symbols.select(&:nterm?)
307
309
  end
308
310
 
311
+ def extract_references
312
+ unless initial_action.nil?
313
+ scanner = StringScanner.new(initial_action.s_value)
314
+ references = []
315
+
316
+ while !scanner.eos? do
317
+ start = scanner.pos
318
+ case
319
+ # $ references
320
+ # It need to wrap an identifier with brackets to use ".-" for identifiers
321
+ when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?\$/) # $$, $<long>$
322
+ tag = scanner[1] ? Lrama::Lexer::Token.new(type: Lrama::Lexer::Token::Tag, s_value: scanner[1]) : nil
323
+ references << [:dollar, "$", tag, start, scanner.pos - 1]
324
+ when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?(\d+)/) # $1, $2, $<long>1
325
+ tag = scanner[1] ? Lrama::Lexer::Token.new(type: Lrama::Lexer::Token::Tag, s_value: scanner[1]) : nil
326
+ references << [:dollar, Integer(scanner[2]), tag, start, scanner.pos - 1]
327
+ when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?([a-zA-Z_][a-zA-Z0-9_]*)/) # $foo, $expr, $<long>program (named reference without brackets)
328
+ tag = scanner[1] ? Lrama::Lexer::Token.new(type: Lrama::Lexer::Token::Tag, s_value: scanner[1]) : nil
329
+ references << [:dollar, scanner[2], tag, start, scanner.pos - 1]
330
+ when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?\[([a-zA-Z_.][-a-zA-Z0-9_.]*)\]/) # $expr.right, $expr-right, $<long>program (named reference with brackets)
331
+ tag = scanner[1] ? Lrama::Lexer::Token.new(type: Lrama::Lexer::Token::Tag, s_value: scanner[1]) : nil
332
+ references << [:dollar, scanner[2], tag, start, scanner.pos - 1]
333
+
334
+ # @ references
335
+ # It need to wrap an identifier with brackets to use ".-" for identifiers
336
+ when scanner.scan(/@\$/) # @$
337
+ references << [:at, "$", nil, start, scanner.pos - 1]
338
+ when scanner.scan(/@(\d+)/) # @1
339
+ references << [:at, Integer(scanner[1]), nil, start, scanner.pos - 1]
340
+ when scanner.scan(/@([a-zA-Z][a-zA-Z0-9_]*)/) # @foo, @expr (named reference without brackets)
341
+ references << [:at, scanner[1], nil, start, scanner.pos - 1]
342
+ when scanner.scan(/@\[([a-zA-Z_.][-a-zA-Z0-9_.]*)\]/) # @expr.right, @expr-right (named reference with brackets)
343
+ references << [:at, scanner[1], nil, start, scanner.pos - 1]
344
+ else
345
+ scanner.getch
346
+ end
347
+ end
348
+
349
+ initial_action.token_code.references = references
350
+ build_references(initial_action.token_code)
351
+ end
352
+
353
+ @printers.each do |printer|
354
+ scanner = StringScanner.new(printer.code.s_value)
355
+ references = []
356
+
357
+ while !scanner.eos? do
358
+ start = scanner.pos
359
+ case
360
+ # $ references
361
+ # It need to wrap an identifier with brackets to use ".-" for identifiers
362
+ when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?\$/) # $$, $<long>$
363
+ tag = scanner[1] ? Lrama::Lexer::Token.new(type: Lrama::Lexer::Token::Tag, s_value: scanner[1]) : nil
364
+ references << [:dollar, "$", tag, start, scanner.pos - 1]
365
+ when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?(\d+)/) # $1, $2, $<long>1
366
+ tag = scanner[1] ? Lrama::Lexer::Token.new(type: Lrama::Lexer::Token::Tag, s_value: scanner[1]) : nil
367
+ references << [:dollar, Integer(scanner[2]), tag, start, scanner.pos - 1]
368
+ when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?([a-zA-Z_][a-zA-Z0-9_]*)/) # $foo, $expr, $<long>program (named reference without brackets)
369
+ tag = scanner[1] ? Lrama::Lexer::Token.new(type: Lrama::Lexer::Token::Tag, s_value: scanner[1]) : nil
370
+ references << [:dollar, scanner[2], tag, start, scanner.pos - 1]
371
+ when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?\[([a-zA-Z_.][-a-zA-Z0-9_.]*)\]/) # $expr.right, $expr-right, $<long>program (named reference with brackets)
372
+ tag = scanner[1] ? Lrama::Lexer::Token.new(type: Lrama::Lexer::Token::Tag, s_value: scanner[1]) : nil
373
+ references << [:dollar, scanner[2], tag, start, scanner.pos - 1]
374
+
375
+ # @ references
376
+ # It need to wrap an identifier with brackets to use ".-" for identifiers
377
+ when scanner.scan(/@\$/) # @$
378
+ references << [:at, "$", nil, start, scanner.pos - 1]
379
+ when scanner.scan(/@(\d+)/) # @1
380
+ references << [:at, Integer(scanner[1]), nil, start, scanner.pos - 1]
381
+ when scanner.scan(/@([a-zA-Z][a-zA-Z0-9_]*)/) # @foo, @expr (named reference without brackets)
382
+ references << [:at, scanner[1], nil, start, scanner.pos - 1]
383
+ when scanner.scan(/@\[([a-zA-Z_.][-a-zA-Z0-9_.]*)\]/) # @expr.right, @expr-right (named reference with brackets)
384
+ references << [:at, scanner[1], nil, start, scanner.pos - 1]
385
+ else
386
+ scanner.getch
387
+ end
388
+ end
389
+
390
+ printer.code.token_code.references = references
391
+ build_references(printer.code.token_code)
392
+ end
393
+
394
+ @error_tokens.each do |error_token|
395
+ scanner = StringScanner.new(error_token.code.s_value)
396
+ references = []
397
+
398
+ while !scanner.eos? do
399
+ start = scanner.pos
400
+ case
401
+ # $ references
402
+ # It need to wrap an identifier with brackets to use ".-" for identifiers
403
+ when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?\$/) # $$, $<long>$
404
+ tag = scanner[1] ? Lrama::Lexer::Token.new(type: Lrama::Lexer::Token::Tag, s_value: scanner[1]) : nil
405
+ references << [:dollar, "$", tag, start, scanner.pos - 1]
406
+ when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?(\d+)/) # $1, $2, $<long>1
407
+ tag = scanner[1] ? Lrama::Lexer::Token.new(type: Lrama::Lexer::Token::Tag, s_value: scanner[1]) : nil
408
+ references << [:dollar, Integer(scanner[2]), tag, start, scanner.pos - 1]
409
+ when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?([a-zA-Z_][a-zA-Z0-9_]*)/) # $foo, $expr, $<long>program (named reference without brackets)
410
+ tag = scanner[1] ? Lrama::Lexer::Token.new(type: Lrama::Lexer::Token::Tag, s_value: scanner[1]) : nil
411
+ references << [:dollar, scanner[2], tag, start, scanner.pos - 1]
412
+ when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?\[([a-zA-Z_.][-a-zA-Z0-9_.]*)\]/) # $expr.right, $expr-right, $<long>program (named reference with brackets)
413
+ tag = scanner[1] ? Lrama::Lexer::Token.new(type: Lrama::Lexer::Token::Tag, s_value: scanner[1]) : nil
414
+ references << [:dollar, scanner[2], tag, start, scanner.pos - 1]
415
+
416
+ # @ references
417
+ # It need to wrap an identifier with brackets to use ".-" for identifiers
418
+ when scanner.scan(/@\$/) # @$
419
+ references << [:at, "$", nil, start, scanner.pos - 1]
420
+ when scanner.scan(/@(\d+)/) # @1
421
+ references << [:at, Integer(scanner[1]), nil, start, scanner.pos - 1]
422
+ when scanner.scan(/@([a-zA-Z][a-zA-Z0-9_]*)/) # @foo, @expr (named reference without brackets)
423
+ references << [:at, scanner[1], nil, start, scanner.pos - 1]
424
+ when scanner.scan(/@\[([a-zA-Z_.][-a-zA-Z0-9_.]*)\]/) # @expr.right, @expr-right (named reference with brackets)
425
+ references << [:at, scanner[1], nil, start, scanner.pos - 1]
426
+ else
427
+ scanner.getch
428
+ end
429
+ end
430
+
431
+ error_token.code.token_code.references = references
432
+ build_references(error_token.code.token_code)
433
+ end
434
+
435
+ @_rules.each do |lhs, rhs, _|
436
+ rhs.each_with_index do |token, index|
437
+ next if token.class == Lrama::Grammar::Symbol || token.type != Lrama::Lexer::Token::User_code
438
+
439
+ scanner = StringScanner.new(token.s_value)
440
+ references = []
441
+
442
+ while !scanner.eos? do
443
+ start = scanner.pos
444
+ case
445
+ # $ references
446
+ # It need to wrap an identifier with brackets to use ".-" for identifiers
447
+ when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?\$/) # $$, $<long>$
448
+ tag = scanner[1] ? Lrama::Lexer::Token.new(type: Lrama::Lexer::Token::Tag, s_value: scanner[1]) : nil
449
+ references << [:dollar, "$", tag, start, scanner.pos - 1]
450
+ when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?(\d+)/) # $1, $2, $<long>1
451
+ tag = scanner[1] ? Lrama::Lexer::Token.new(type: Lrama::Lexer::Token::Tag, s_value: scanner[1]) : nil
452
+ references << [:dollar, Integer(scanner[2]), tag, start, scanner.pos - 1]
453
+ when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?([a-zA-Z_][a-zA-Z0-9_]*)/) # $foo, $expr, $<long>program (named reference without brackets)
454
+ tag = scanner[1] ? Lrama::Lexer::Token.new(type: Lrama::Lexer::Token::Tag, s_value: scanner[1]) : nil
455
+ references << [:dollar, scanner[2], tag, start, scanner.pos - 1]
456
+ when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?\[([a-zA-Z_.][-a-zA-Z0-9_.]*)\]/) # $expr.right, $expr-right, $<long>program (named reference with brackets)
457
+ tag = scanner[1] ? Lrama::Lexer::Token.new(type: Lrama::Lexer::Token::Tag, s_value: scanner[1]) : nil
458
+ references << [:dollar, scanner[2], tag, start, scanner.pos - 1]
459
+
460
+ # @ references
461
+ # It need to wrap an identifier with brackets to use ".-" for identifiers
462
+ when scanner.scan(/@\$/) # @$
463
+ references << [:at, "$", nil, start, scanner.pos - 1]
464
+ when scanner.scan(/@(\d+)/) # @1
465
+ references << [:at, Integer(scanner[1]), nil, start, scanner.pos - 1]
466
+ when scanner.scan(/@([a-zA-Z][a-zA-Z0-9_]*)/) # @foo, @expr (named reference without brackets)
467
+ references << [:at, scanner[1], nil, start, scanner.pos - 1]
468
+ when scanner.scan(/@\[([a-zA-Z_.][-a-zA-Z0-9_.]*)\]/) # @expr.right, @expr-right (named reference with brackets)
469
+ references << [:at, scanner[1], nil, start, scanner.pos - 1]
470
+
471
+ when scanner.scan(/\/\*/)
472
+ scanner.scan_until(/\*\//)
473
+ else
474
+ scanner.getch
475
+ end
476
+ end
477
+
478
+ token.references = references
479
+ token.numberize_references(lhs, rhs)
480
+ build_references(token)
481
+ end
482
+ end
483
+ end
484
+
485
+ def create_token(type, s_value, line, column)
486
+ t = Token.new(type: type, s_value: s_value)
487
+ t.line = line
488
+ t.column = column
489
+
490
+ return t
491
+ end
492
+
309
493
  private
310
494
 
311
495
  def find_nterm_by_id!(id)
@@ -470,7 +654,9 @@ module Lrama
470
654
 
471
655
  # Fill #number and #token_id
472
656
  def fill_symbol_number
473
- # TODO: why start from 256
657
+ # Character literal in grammar file has
658
+ # token id corresponding to ASCII code by default,
659
+ # so start token_id from 256.
474
660
  token_id = 256
475
661
 
476
662
  # YYEMPTY = -2