Class: FuPeg::Grammar

Inherits:
Object
  • Object
show all
Defined in:
lib/fupeg/grammar.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parser) ⇒ Grammar

Returns a new instance of Grammar.



42
43
44
45
46
47
# File 'lib/fupeg/grammar.rb', line 42

def initialize(parser)
  @p = parser
  self.class.used_grams.each do |iv, v|
    instance_variable_set(iv, v.new(parser))
  end
end

Class Method Details

.create(str, pos = 0) ⇒ Object



7
8
9
10
11
# File 'lib/fupeg/grammar.rb', line 7

def self.create(str, pos = 0)
  parser = Parser.new(str, pos)
  grammar = new(parser)
  [parser, grammar]
end

.parse(root, str) ⇒ Object



13
14
15
16
# File 'lib/fupeg/grammar.rb', line 13

def self.parse(root, str)
  _, gr = create(str)
  gr.__send__(root)
end

.proxy(*meths, to:) ⇒ Object



30
31
32
33
34
35
36
# File 'lib/fupeg/grammar.rb', line 30

def self.proxy(*meths, to:)
  meths.each do |meth|
    define_method(meth) { |*args, &block|
      instance_variable_get(to).__send__(meth, *args, &block)
    }
  end
end

.use_gram(gram, as: nil) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
# File 'lib/fupeg/grammar.rb', line 18

def self.use_gram(gram, *, as: nil)
  if as.nil?
    name = gram.name[/\w+$/]
    name = name.gsub(/(?<!^)(?=[A-Z](?![A-Z\d_]))/, "_").downcase
    as = :"@#{name}"
  elsif !as.start_with?("@")
    as = :"@#{as}"
  end
  @used_grams ||= {}
  @used_grams[as] = gram
end

.used_gramsObject



38
39
40
# File 'lib/fupeg/grammar.rb', line 38

def self.used_grams
  @used_grams&.dup || {}
end

Instance Method Details

#_(lit = nil, &block) ⇒ Object



57
58
59
# File 'lib/fupeg/grammar.rb', line 57

def _(lit = nil, &block)
  @p.match(lit, &block)
end

#_is_ident?(tok) ⇒ Boolean

Returns:

  • (Boolean)


141
142
143
144
145
146
# File 'lib/fupeg/grammar.rb', line 141

def _is_ident?(tok)
  @_is_ident ||= Hash.new { |h, k|
    h[k] = self.class.parse(:ident_only, k) == k
  }
  @_is_ident[tok]
end

#`(token) ⇒ Object

raw token match if token is ident, then exact match performed with whole next ident else only string match and then whitespace is consumed



131
132
133
134
135
136
137
138
139
# File 'lib/fupeg/grammar.rb', line 131

def `(token)
  @p.match {
    if _is_ident?(token)
      _{ ident_only == token } || fail!(pat: token)
    else
      @p.match(token)
    end && token_sp? && token
  }
end

#cont?(&block) ⇒ Boolean

Returns:

  • (Boolean)


85
86
87
# File 'lib/fupeg/grammar.rb', line 85

def cont?(&block)
  @p.current_cutpoint.can_continue? && (block ? @p.backtrack(&block) : true)
end

#cut(&block) ⇒ Object



77
78
79
# File 'lib/fupeg/grammar.rb', line 77

def cut(&block)
  @p.with_cut_point(&block)
end

#cut!Object



81
82
83
# File 'lib/fupeg/grammar.rb', line 81

def cut!
  @p.current_cutpoint.cut!
end

#dotObject



53
54
55
# File 'lib/fupeg/grammar.rb', line 53

def dot
  @p.dot
end

#eofObject

specialized matchers



95
96
97
# File 'lib/fupeg/grammar.rb', line 95

def eof
  @p.eof? && :eof
end

#eolObject



103
104
105
# File 'lib/fupeg/grammar.rb', line 103

def eol
  _ { lnsp? && nl && :eol }
end

#fail!(pat: nil) ⇒ Object



49
50
51
# File 'lib/fupeg/grammar.rb', line 49

def fail!(pat: nil)
  @p.fail!(pat: pat, skip: 3)
end

#identObject



123
124
125
# File 'lib/fupeg/grammar.rb', line 123

def ident
  (w = ident_only) && token_sp? && w
end

#ident_onlyObject



148
149
150
# File 'lib/fupeg/grammar.rb', line 148

def ident_only
  txt(/[a-zA-Z_]\w*/)
end

#lnsp!Object



111
112
113
# File 'lib/fupeg/grammar.rb', line 111

def lnsp!
  _(/[ \t]+/)
end

#lnsp?Boolean

Returns:

  • (Boolean)


107
108
109
# File 'lib/fupeg/grammar.rb', line 107

def lnsp?
  _(/[ \t]*/)
end

#nlObject



99
100
101
# File 'lib/fupeg/grammar.rb', line 99

def nl
  _(/\r\n|\r|\n/)
end

#opt(arg = nil, &block) ⇒ Object



61
62
63
# File 'lib/fupeg/grammar.rb', line 61

def opt(arg = nil, &block)
  @p.match(arg, &block) || true
end

#rep(range = 0, lit = nil, &block) ⇒ Object



89
90
91
# File 'lib/fupeg/grammar.rb', line 89

def rep(range = 0.., lit = nil, &block)
  @p.repetition(range, lit, &block)
end

#sp!Object



115
116
117
# File 'lib/fupeg/grammar.rb', line 115

def sp!
  _(/\s+/)
end

#sp?Boolean

Returns:

  • (Boolean)


119
120
121
# File 'lib/fupeg/grammar.rb', line 119

def sp?
  _(/\s*/)
end

#token_sp?Boolean

Returns:

  • (Boolean)


152
153
154
# File 'lib/fupeg/grammar.rb', line 152

def token_sp?
  _(/\s*/)
end

#txt(lit = nil, &block) ⇒ Object



73
74
75
# File 'lib/fupeg/grammar.rb', line 73

def txt(lit = nil, &block)
  @p.text(lit, &block)
end

#will?(lit = nil, &block) ⇒ Boolean

Returns:

  • (Boolean)


65
66
67
# File 'lib/fupeg/grammar.rb', line 65

def will?(lit = nil, &block)
  @p.look_ahead(true, lit, &block)
end

#wont!(lit = nil, &block) ⇒ Object



69
70
71
# File 'lib/fupeg/grammar.rb', line 69

def wont!(lit = nil, &block)
  @p.look_ahead(false, lit, &block)
end