Module: Drawght::Parser

Included in:
Compiler
Defined in:
lib/drawght/parser.rb

Defined Under Namespace

Classes: SyntaxError

Constant Summary collapse

TOKENS =
[
  PREFIX = '{',
  SUFFIX = '}',
  ACCESSOR = '.',
  INDEX = '#',
  SCOPE = ':',
  CONTEXT = '@',
  LAST = '$',
  LENGTH = '&',
]
IDENTIFIER_MATCHES =

Identifiers/name matches:

  • “name”

  • “variable name”

  • “variable-name”

  • “variable_name”

  • name

  • “name_”

  • “_name”

"[A-Za-z_][A-Za-z0-9_\\-]*(?: [A-Za-z0-9_\\-]+)*"
INDEX_MATCHES =

Index/item matches:

  • “#1” for first item.

  • “#n” for n-th item.

  • “#$” for last item.

"\\#{INDEX}(?:\\d+|\\#{LAST})"
ELEMENT_MATCHES =

Element matches:

  • “items#1” for first named item.

  • “items#n” for n-th named item.

  • “items#$” for last named item.

Matches with IDENTIFIER_MATCHES and INDEX_MATCHES.

"#{IDENTIFIER_MATCHES}(?:#{INDEX_MATCHES})?"
ATTRIBUTE_MATCHES =

Attribute matches.

"\\#{ACCESSOR}(?:#{ELEMENT_MATCHES})"
VALIDATION_PATTERN =

Validation

Structural matches:

  • “struct.attribute” for attribute value from struct.

  • “struct.substruct.attribute” for attribute value of the substruct from struct.

  • “struct.items#1” for first item value in items of the struct.

  • “struct.items#1.attribute” for attribute value of the first item in items of the struct.

  • “#1.attribute” for attribute value of the first item.

  • “#1.struct.attribute” for attribute value of the struct from the first item.

  • “items#1.attribute” for attribute value of the first item in items.

  • “items#1.struct.attribute” for attribute value of the struct of the first item in items.

  • “items#1.subitems#1” for subitem value of the first item in items.

  • “items#1.subitems#1.attribute” for attribute value of the subitem from first item in items.

Scoped matches:

“:attribute” “:collection:attribute” “collection:attribute” “collection:subcollection:attribute” “items#1:attribute” “struct.collection:attribute” “items#1.collection:attribute” “items#1.subitems#1:attribute” “items#1.subitems#1.collection:attribute” “struct.collection:noitcelloc.tcurts:attribute”

Regexp.new "^(?=.*[A-Za-z_\\#{INDEX}])(?:(?:#{ELEMENT_MATCHES}|#{INDEX_MATCHES})(?:#{ATTRIBUTE_MATCHES})*)?(?:\\#{SCOPE}(?:#{ELEMENT_MATCHES})(?:#{ATTRIBUTE_MATCHES})*)*(?:\\#{INDEX}\\#{LENGTH})?$"
PLACEHOLDERS_PATTERN =
Regexp.new "\\#{PREFIX}([^\\#{SUFFIX}]+)\\#{SUFFIX}"
STRUCTURE_TOKEN_PATTERN =
Regexp.new "(\\#{ACCESSOR}|\\#{INDEX}|\\#{LENGTH}$)"
SCOPE_TOKEN_PATTERN =
Regexp.new "(\\#{SCOPE})"
SCOPE_PATH_PATTERN =
Regexp.new "^(.*)#{SCOPE_TOKEN_PATTERN}(.*)$"
NUMBER_PATTERN =
/^\d+/

Instance Method Summary collapse

Instance Method Details

#has_placeholders?(string) ⇒ Boolean

Returns:

  • (Boolean)


155
156
157
# File 'lib/drawght/parser.rb', line 155

def has_placeholders? string
  string.match? PLACEHOLDERS_PATTERN
end

#mapping_placeholders_from(string) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/drawght/parser.rb', line 131

def mapping_placeholders_from string
  clear_placeholder_mappings!

  placeholders_from(string).map do |placeholder|
    if placeholder =~ SCOPE_TOKEN_PATTERN
      placeholder.scan SCOPE_PATH_PATTERN do |pathkeys, _delimiter, attribute|
        (sequential_placeholders[pathkeys] ||= {}).update placeholder => attribute
      end
    else
      structural_placeholders.add_unique placeholder
    end

    placeholder
  end
end

#pathize(string) ⇒ Object



159
160
161
# File 'lib/drawght/parser.rb', line 159

def pathize string
  "#{PREFIX}#{string}#{SUFFIX}"
end

#pathkeys_from(string) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/drawght/parser.rb', line 106

def pathkeys_from string
  raise SyntaxError.new string unless syntax_valid? string

  path = case string
    when STRUCTURE_TOKEN_PATTERN then
      pathkeys_for_structure string
    when SCOPE_TOKEN_PATTERN then
      pathkeys_for_collection string
    else
      [string]
  end

  path.flatten
end

#placeholders_from(string) ⇒ Object



125
126
127
128
129
# File 'lib/drawght/parser.rb', line 125

def placeholders_from string
  return [] unless string =~ PLACEHOLDERS_PATTERN

  string.scan(PLACEHOLDERS_PATTERN).flatten
end

#sequential_placeholdersObject



151
152
153
# File 'lib/drawght/parser.rb', line 151

def sequential_placeholders
  @sequential_placeholders ||= {}
end

#structural_placeholdersObject



147
148
149
# File 'lib/drawght/parser.rb', line 147

def structural_placeholders
  @structural_placeholders ||= []
end

#syntax_valid?(string) ⇒ Boolean

Returns:

  • (Boolean)


121
122
123
# File 'lib/drawght/parser.rb', line 121

def syntax_valid? string
  string.match? VALIDATION_PATTERN
end