Class: Lilac::Directives::ClassParser

Inherits:
Object
  • Object
show all
Defined in:
lib/lilac/directives/class_parser.rb

Overview

Parser for the data-class hash literal grammar.

Duplicate pair (build-time / runtime). See decisions §17.

{ active: @is_active, 'btn-primary': @primary, "hover:bg-blue": @h }

Returns Array<[key_string, value_string]> in source order. Keys are returned as plain strings (quotes stripped); values are the raw text between : and the next , / }, leaving value- grammar validation (ivar / bare ident) to the caller (Scanner).

Quoted keys may contain : (Tailwind variants like 'hover:bg-blue-500'), so a naive split-on-colon would break. The grammar is stricter than JSON (forbids ;, control chars, whitespace inside keys) and looser elsewhere (bare Ruby idents as keys, no string quoting on values).

Per-character checks use char comparisons rather than JS-bridged Regexp.test calls because they run in inner loops; whole-string validates use Regexp.

Defined Under Namespace

Classes: Error

Constant Summary collapse

BARE_KEY =
/^[a-zA-Z_][a-zA-Z0-9_]*$/

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source) ⇒ ClassParser

Returns a new instance of ClassParser.



39
40
41
42
# File 'lib/lilac/directives/class_parser.rb', line 39

def initialize(source)
  @src = source.to_s
  @pos = 0
end

Class Method Details

.parse(source) ⇒ Object

Spec 6.4: quoted-key body forbids whitespace, control chars (\x00-\x1F + \x7F), ;, and any quote character. Checked via valid_quoted_body? (char-walk) instead of a Regexp because mruby-regexp-compat doesn't support \xHH hex escapes inside character classes — [^\s\\'";\x00-\x1F\x7F] mis-parses as a class containing literal x/0/etc.



35
36
37
# File 'lib/lilac/directives/class_parser.rb', line 35

def self.parse(source)
  new(source).parse
end

Instance Method Details

#parseObject



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/lilac/directives/class_parser.rb', line 44

def parse
  skip_ws
  expect("{")
  skip_ws
  pairs = []
  unless peek == "}"
    pairs << parse_pair
    loop do
      skip_ws
      break unless peek == ","
      advance
      skip_ws
      pairs << parse_pair
    end
  end
  skip_ws
  expect("}")
  skip_ws
  if @pos < @src.length
    raise Error, "unexpected trailing content: #{@src[@pos..].inspect}"
  end
  pairs
end