Class: Dms::Tier1::T1Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/dms/tier1.rb

Constant Summary collapse

SP =

Byte constants (reused from Parser)

0x20
TAB =
0x09
LF =
0x0A
CR =
0x0D
LBRACK =
0x5B
RBRACK =
0x5D
LBRACE =
0x7B
RBRACE =
0x7D
LPAREN =

‘(’

0x28
RPAREN =

‘)’

0x29
COMMA =
0x2C
DOT =
0x2E
PLUS =
0x2B
COLON =
0x3A
DQUOTE =
0x22
SQUOTE =
0x27
UNDERSCORE =
0x5F
DIGIT0 =
0x30
DIGIT9 =
0x39
LOWER_A =
0x61
LOWER_Z =
0x7A
UPPER_A =
0x41
UPPER_Z =
0x5A
MINUS =
0x2D
HASH =
0x23
BARE_KEY_BYTE =
Array.new(256, false)
RESERVED_SIGIL_BYTE =
Array.new(256, false)

Instance Method Summary collapse

Constructor Details

#initialize(src) ⇒ T1Parser

Returns a new instance of T1Parser.



602
603
604
605
606
607
# File 'lib/dms/tier1.rb', line 602

def initialize(src)
  @src_original = src
  @decorators = []    # Array of DecoratorEntry (sidecar)
  @imports = []
  @observed_tier = 0
end

Instance Method Details

#detect_tier(src) ⇒ Object

Quick scan for _dms_tier value without full parse.



626
627
628
629
630
631
632
633
634
635
636
# File 'lib/dms/tier1.rb', line 626

def detect_tier(src)
  # Look for _dms_tier in front matter using a regex-like scan.
  # Only look inside the +++ ... +++ block.
  s = src.dup.force_encoding("UTF-8")
  m = s.match(/\A\s*\+\+\+[^\n]*\n(.*?)\n\+\+\+/m)
  return 0 unless m
  fm_content = m[1]
  m2 = fm_content.match(/^_dms_tier\s*:\s*(\d+)/)
  return 0 unless m2
  m2[1].to_i
end

#parseObject



609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
# File 'lib/dms/tier1.rb', line 609

def parse
  # Step 1: Pre-scan to detect tier without triggering the tier-1 rejection.
  tier = detect_tier(@src_original)

  # If tier-0 input, wrap as tier-0 result
  if tier == 0
    doc = Dms::Parser.parse_document(@src_original)
    return DocumentT1.new(doc, [], [], 0)
  end

  @observed_tier = tier

  # Tier-1 parse: handle _dms_tier: 1 in front matter and parse decorators.
  parse_tier1_document
end

#sigil_at?(pos) ⇒ Boolean

True if the position ‘pos` in @src starts a sigil atom: either an ASCII reserved sigil char or a reserved-emoji codepoint.

Returns:

  • (Boolean)


593
594
595
596
597
598
599
600
# File 'lib/dms/tier1.rb', line 593

def sigil_at?(pos)
  return false if pos >= @len
  b = @src.getbyte(pos)
  return false if b.nil?
  return true if RESERVED_SIGIL_BYTE[b]
  return false if b < 0x80
  Tier1.sigil_atom_start_at?(@src, pos)
end