Class: Resyma::RegexBuildVistor

Inherits:
Object
  • Object
show all
Includes:
Core::RegexpOp
Defined in:
lib/resyma/language.rb

Overview

An visitor which builds automaton. The particular syntax is defined as follow:

regex: char | seq | rep | or | opt char: STRING | ID | ID ‘(’ STRING ‘)’ seq: ‘(’ regex (‘;’ regex)+ ‘)’ rep: regex ‘..’ | regex ‘…’ or: ‘[’ regex (‘,’ regex)+ ‘]’ opt: ‘[’ regex ‘]’

Instance Method Summary collapse

Methods included from Core::RegexpOp

#rcat, #rchr, #reps, #ror, #rrep

Instance Method Details

#build_char(type, value) ⇒ Object



80
81
82
# File 'lib/resyma/language.rb', line 80

def build_char(type, value)
  rchr(Core::PTNodeMatcher.new(type, value))
end

#build_opt(ast) ⇒ Object



113
114
115
116
117
# File 'lib/resyma/language.rb', line 113

def build_opt(ast)
  value = ast.children[0]
  regex = visit(value)
  ror(reps, regex)
end

#build_or(ast) ⇒ Object



102
103
104
105
106
107
108
109
110
111
# File 'lib/resyma/language.rb', line 102

def build_or(ast)
  n = ast.children.length
  unless n > 1
    raise IllegalRegexError,
          "Or-regex must contain two or more branches, but found #{n}"
  end

  regex_lst = ast.children.map { |sub| visit(sub) }
  ror(*regex_lst)
end

#build_rep(ast, one_or_more) ⇒ Object

Raises:



89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/resyma/language.rb', line 89

def build_rep(ast, one_or_more)
  left, right = ast.children
  raise IllegalRegexError, "Beginless range is illegal" if left.nil?
  raise IllegalRegexError, "Only endless range is legal" unless right.nil?

  regex = visit(left)
  if one_or_more
    rcat(regex, rrep(regex))
  else
    rrep(regex)
  end
end

#build_seq(ast) ⇒ Object



84
85
86
87
# File 'lib/resyma/language.rb', line 84

def build_seq(ast)
  regex_lst = ast.children.map { |sub| visit(sub) }
  rcat(*regex_lst)
end

#visit(ast) ⇒ Resyma::Core::Regexp

Build a Resyma::Core::Automaton from an AST

Parameters:

  • ast (Parser::AST::Node)

    An abstract syntax tree

Returns:



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/resyma/language.rb', line 33

def visit(ast)
  case ast.type
  when :array
    if ast.children.length > 1
      build_or ast
    elsif ast.children.empty?
      raise IllegalRegexError, "Empty array is illegal"
    else
      build_opt ast
    end
  when :begin
    build_seq(ast)
  when :irange
    build_rep(ast, false)
  when :erange
    build_rep(ast, true)
  when :str
    value = ast.children.first
    type = Core::CONST_TOKEN_TABLE[value]
    if type.nil?
      raise IllegalRegexError,
            "Unknown constant token [#{value}]"
    end
    build_char(type, value)
  when :send
    rec, type, *args = ast.children
    raise IllegalRegexError, "Reciever #{rec} is illegal" unless rec.nil?

    if args.length > 1
      raise IllegalRegexError,
            "Two or more arguments is illegal"
    end

    return build_char(type, nil) if args.empty?

    value = args.first
    if value.type == :str
      build_char(type, value.children.first)
    else
      raise IllegalRegexError,
            "Character regex only accepts static string as value, got " +
            value.type.to_s
    end
  end
end