class Praat::Lexer

Constants

FLOAT
INTEGER
LETTER
NUMBER
WORD

Attributes

filename[RW]
match[RW]
ss[RW]
state[RW]

Public Instance Methods

action() { || ... } click to toggle source
# File lib/praat_lexer.rex.rb, line 33
def action
  yield
end
do_parse() click to toggle source
# File lib/praat_lexer.rb, line 6
def do_parse 
  output = [] 
  while token = next_token do
    type, *vals = token
    output << send("lex_#{type}", *vals)
  end
  output
end
lex_collection(collection) click to toggle source
# File lib/praat_lexer.rb, line 27
def lex_collection collection
  [:collection, collection.chomp]
end
lex_float_property(property, value) click to toggle source
# File lib/praat_lexer.rb, line 15
def lex_float_property property, value
  [:property, property.chomp, value.to_f]
end
lex_indent(spaces) click to toggle source
# File lib/praat_lexer.rb, line 35
def lex_indent spaces
  indents = spaces.length / 4
  [:indent, indents]
end
lex_integer_property(property, value) click to toggle source
# File lib/praat_lexer.rb, line 19
def lex_integer_property property, value
  [:property, property.chomp, value.to_i]
end
lex_object(object, index) click to toggle source
# File lib/praat_lexer.rb, line 31
def lex_object object, index
  [:object, object.chomp, index.to_i]
end
lex_string_property(property, value) click to toggle source
# File lib/praat_lexer.rb, line 23
def lex_string_property property, value
  [:property, property.chomp, value.chomp]
end
matches() click to toggle source
# File lib/praat_lexer.rex.rb, line 27
def matches
  m = (1..9).map { |i| ss[i] }
  m.pop until m[-1] or m.empty?
  m
end
next_token() click to toggle source
# File lib/praat_lexer.rex.rb, line 56
def next_token

  token = nil

  until ss.eos? or token do
    token =
      case state
      when nil then
        case
        when text = ss.scan(/(#{WORD}) = (#{FLOAT})/) then
          action { [:float_property, *matches] }
        when text = ss.scan(/(#{WORD}) = (#{INTEGER})/) then
          action { [:integer_property, *matches] }
        when text = ss.scan(/(#{WORD}) = "(#{WORD}|)"/) then
          action { [:string_property, *matches] }
        when text = ss.scan(/(#{WORD}) \[\]:/) then
          action { [:collection, *matches] }
        when text = ss.scan(/(intervals): size = #{INTEGER}.*/) then
          action { [:collection, *matches] }
        when text = ss.scan(/(#{WORD}) \[(#{INTEGER})\]:/) then
          action { [:object, *matches] }
        when text = ss.scan(/( {4}+)/) then
          action { [:indent, *matches] }
        when text = ss.scan(/\s*\n/) then
          # do nothing
        when text = ss.scan(/tiers\?.*/) then
          # do nothing
        else
          text = ss.string[ss.pos .. -1]
          raise ScanError, "can not match (#{state.inspect}): '#{text}'"
        end
      else
        raise ScanError, "undefined state: '#{state}'"
      end # token = case state

    next unless token # allow functions to trigger redo w/ nil
  end # while

  raise "bad lexical result: #{token.inspect}" unless
    token.nil? || (Array === token && token.size >= 2)

  # auto-switch state
  self.state = token.last if token && token.first == :state

  token
end
parse(str) click to toggle source
# File lib/praat_lexer.rex.rb, line 42
def parse str
  self.ss     = scanner_class.new str
  self.state  ||= nil

  do_parse
end
parse_file(path) click to toggle source
# File lib/praat_lexer.rex.rb, line 49
def parse_file path
  self.filename = path
  open path do |f|
    parse f.read
  end
end
scanner_class() click to toggle source
# File lib/praat_lexer.rex.rb, line 38
def scanner_class
  StringScanner
end