class Object

Constants

Pattern

Pattern is a class alias for RepeatablePattern

class Pattern # <- encase people ctrl+F for “class Pattern”

Public Instance Methods

break_left(arr) { |elem)| ... } click to toggle source

Split arr in two Walks arr from left to right and splits it on the first element that the block returns false this means that the block returned true for all lements in the left half and false for the first element of the right half the order of elements is not changed

@param [Array] arr The array to break

@yield [RegexOperator,String] the element to check

@return [Array<(Array,Array)>] The two halfs

# File lib/ruby_grammar_builder/regex_operator.rb, line 17
def break_left(arr)
    left = arr.take_while do |elem|
        next !(yield elem)
    end
    [left, arr[(left.length)..-1]]
end
break_right(arr) { |elem)| ... } click to toggle source

(@see break_left) Walks the array from right to left spliting where the block returns false

# File lib/ruby_grammar_builder/regex_operator.rb, line 28
def break_right(arr)
    right = arr.reverse.take_while do |elem|
        next !(yield elem)
    end.reverse
    [arr[0..-(right.length+1)], right]
end
filter_options(plugin, pattern, default) click to toggle source

Filters a {PatternBase#original_arguments} to just the options required for a plugin

@api private

@param [GrammarPlugin] plugin The plugin to filter options @param [PatternBase, Symbol, Hash] pattern the pattern with options to filter @param [Hash] default the default options to supply to the plugin

@return [Hash] the filtered options

# File lib/ruby_grammar_builder/grammar_plugin.rb, line 179
def filter_options(plugin, pattern, default)
    options = {}
    if pattern.is_a? PatternBase
        options = pattern.original_arguments.select { |k| plugin.class.options.include? k }
    end
    options.merge(default)
end
fixup_value(value) click to toggle source

Fixes value to be either a PatternBase, Symbol, or Array of either

@param [*] value The value to fixup

@return [PatternBase,Symbol,Array<PatternBase,Symbol>] the fixed value

# File lib/ruby_grammar_builder/util.rb, line 114
def fixup_value(value)
    is_array = value.is_a? Array
    # ensure array is flat and only contains patterns or symbols
    value = [value].flatten.map do |v|
        next v if v.is_a? Symbol

        if v.is_a? String
            next v if v.start_with?("source.", "text.", "$")
        end

        if v.is_a? Hash
            # check for an implicit legacy pattern
            legacy_keys = [
                :name,
                :contentName,
                :begin,
                :end,
                :while,
                :comment,
                :disabled,
                :patterns,
            ]
            v = LegacyPattern.new(v) unless (v.keys.map(&:to_sym) & legacy_keys).empty?
        end

        v = Pattern.new(v) unless v.is_a? PatternBase
        v
    end

    value = value[0] unless is_array
    value
end
get_tags(output) click to toggle source

Converts an output into a set of tags

@param [Hash] output output of Grammar#generate

@return [Set<String>] The tags in the grammar

# File lib/ruby_grammar_builder/util.rb, line 180
def get_tags(output)
    repository = output[:repository]
    repository[:$initial_context] = {patterns: output[:patterns]}
    tags = Set.new
    add_tags = lambda do |rule|
        rule = rule.transform_keys(&:to_sym)
        tags.merge(rule[:name].split(" ")) if rule[:name]
        tags.merge(rule[:contentName].split(" ")) if rule[:contentName]

        rule[:patterns]&.each { |p| add_tags.call(p) }
        rule[:captures]&.values&.each { |p| add_tags.call(p) }
        rule[:beginCaptures]&.values&.each { |p| add_tags.call(p) }
        rule[:endCaptures]&.values&.each { |p| add_tags.call(p) }
        rule[:whileCaptures]&.values&.each { |p| add_tags.call(p) }
    end

    repository.values.each { |p| add_tags.call(p) }

    tags
end
lookAheadFor(pattern) click to toggle source

(see PatternBase#lookAheadFor)

# File lib/ruby_grammar_builder/pattern_extensions/look_ahead_for.rb, line 25
def lookAheadFor(pattern)
    if pattern.is_a? Hash
        pattern[:type] = :lookAheadFor
    else
        pattern = {match: pattern, type: :lookAheadFor}
    end
    lookAround(pattern)
end
lookAheadToAvoid(pattern) click to toggle source

(see PatternBase#lookAheadToAvoid)

# File lib/ruby_grammar_builder/pattern_extensions/look_ahead_to_avoid.rb, line 24
def lookAheadToAvoid(pattern)
    if pattern.is_a? Hash
        pattern[:type] = :lookAheadToAvoid
    else
        pattern = {match: pattern, type: :lookAheadToAvoid}
    end
    lookAround(pattern)
end
lookAround(pattern) click to toggle source

(see PatternBase#lookAround)

# File lib/ruby_grammar_builder/pattern_extensions/lookaround_pattern.rb, line 125
def lookAround(pattern)
    LookAroundPattern.new(pattern)
end
lookBehindFor(pattern) click to toggle source

(see PatternBase#lookBehindFor)

# File lib/ruby_grammar_builder/pattern_extensions/look_behind_for.rb, line 24
def lookBehindFor(pattern)
    if pattern.is_a? Hash
        pattern[:type] = :lookBehindFor
    else
        pattern = {match: pattern, type: :lookBehindFor}
    end
    lookAround(pattern)
end
lookBehindToAvoid(pattern) click to toggle source

(see PatternBase#lookBehindToAvoid)

# File lib/ruby_grammar_builder/pattern_extensions/look_behind_to_avoid.rb, line 24
def lookBehindToAvoid(pattern)
    if pattern.is_a? Hash
        pattern[:type] = :lookBehindToAvoid
    else
        pattern = {match: pattern, type: :lookBehindToAvoid}
    end
    lookAround(pattern)
end
matchResultOf(reference) click to toggle source

(see PatternBase#matchResultOf)

# File lib/ruby_grammar_builder/pattern_extensions/match_result_of.rb, line 65
def matchResultOf(reference)
    MatchResultOfPattern.new(reference)
end
maybe(pattern) click to toggle source

(see PatternBase#maybe)

# File lib/ruby_grammar_builder/pattern_extensions/maybe.rb, line 48
def maybe(pattern)
    MaybePattern.new(pattern)
end
oneOf(patterns) click to toggle source

(see PatternBase#oneOf)

# File lib/ruby_grammar_builder/pattern_extensions/one_of.rb, line 105
def oneOf(patterns)
    OneOfPattern.new(patterns)
end
oneOrMoreOf(pattern) click to toggle source

(see PatternBase#oneOrMoreOf)

# File lib/ruby_grammar_builder/pattern_extensions/one_or_more_of.rb, line 40
def oneOrMoreOf(pattern)
    OneOrMoreOfPattern.new(pattern)
end
placeholder(placeholder) click to toggle source

(see PatternBase#placeholder)

# File lib/ruby_grammar_builder/pattern_extensions/placeholder.rb, line 100
def placeholder(placeholder)
    PlaceholderPattern.new(placeholder)
end
recursivelyMatch(reference) click to toggle source

(see PatternBase#recursivelyMatch)

# File lib/ruby_grammar_builder/pattern_extensions/recursively_match.rb, line 74
def recursivelyMatch(reference)
    RecursivelyMatchPattern.new(reference)
end
resolve_require(path) click to toggle source

Determine the absolute path that a require statement resolves to

@note this assumes path was successfully required previously

@param [String] path the path to resolve

@return [String] the resolved path

# File lib/ruby_grammar_builder/util.rb, line 156
def resolve_require(path)
    path = Pathname.new path
    return path.to_s if path.absolute? && path.extname != ""

    return path.dirname.glob("#{path.basename}.{rb,so,dll}")[0].to_s if path.absolute?

    $LOAD_PATH.each do |p|
        test_path = Pathname.new(p).join(path)
        return test_path.to_s if path.extname != "" && test_path.exist?

        test_paths = test_path.dirname.glob("#{test_path.basename}.{rb,so,dll}")
        return test_paths[0].to_s unless test_paths.empty?
    end

    ""
end
string_single_entity?(regex_string) click to toggle source

determines if a regex string is a single entity

@note single entity means that for the purposes of modification, the expression is

atomic, for example if appending a +*+ to the end of +regex_string+ matches only
a part of regex string multiple times then it is not a single_entity

@param regex_string [String] a string representing a regular expression, without the

forward slash "/" at the beginning and

@return [Boolean] if the string represents an single regex entity

# File lib/ruby_grammar_builder/util.rb, line 53
def string_single_entity?(regex_string)
    escaped = false
    in_set = false
    depth = 0
    regex_string.each_char.with_index do |c, index|
        # allow the first character to be at depth 0
        # NOTE: this automatically makes a single char regexp a single entity
        return false if depth == 0 && index != 0

        if escaped
            escaped = false
            next
        end
        if c == '\\'
            escaped = true
            next
        end
        if in_set
            if c == ']'
                in_set = false
                depth -= 1
            end
            next
        end
        case c
        when "(" then depth += 1
        when ")" then depth -= 1
        when "["
            depth += 1
            in_set = true
        end
    end
    # sanity check
    if depth != 0 or escaped or in_set
        puts "Internal error: when determining if a Regexp is a single entity"
        puts "an unexpected sequence was found. This is a bug with the gem."
        puts "This will not effect the validity of the produced grammar"
        puts "Regexp: #{inspect} depth: #{depth} escaped: #{escaped} in_set: #{in_set}"
        return false
    end
    true
end
with_no_warnings() { || ... } click to toggle source

Disables warnings for the block

@return [void]

# File lib/ruby_grammar_builder/util.rb, line 9
def with_no_warnings
    old_verbose = $VERBOSE
    $VERBOSE = nil
    yield
ensure
    $VERBOSE = old_verbose
end
wrap_with_anchors(pat) click to toggle source

Wraps a pattern in start and end anchors

@param [PatternBase] pat the pattern to wrap

@return [PatternBase] the wrapped pattern

# File lib/ruby_grammar_builder/util.rb, line 103
def wrap_with_anchors(pat)
    Pattern.new(/^/).then(Pattern.new(pat)).then(/$/)
end
zeroOrMoreOf(pattern) click to toggle source

(see PatternBase#zeroOrMoreOf)

# File lib/ruby_grammar_builder/pattern_extensions/zero_or_more_of.rb, line 48
def zeroOrMoreOf(pattern)
    ZeroOrMoreOfPattern.new(pattern)
end