Class: BracketNotation::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/bracket_notation/parser.rb

Overview

This class represents a parser for sentences annotated with the kind of bracket notation that is commonly used by linguists. After being checked for obvious problems, the input string is scanned for tokens, which are evaluated to produce an expression tree.

Defined Under Namespace

Classes: ValidationError

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(input) ⇒ Parser

Saves the input string, as well as a copy of the input string that has been normalized and validated.



73
74
75
76
# File 'lib/bracket_notation/parser.rb', line 73

def initialize(input)
  @input = input
  validate
end

Instance Attribute Details

#inputObject (readonly)

Returns the value of attribute input.



35
36
37
# File 'lib/bracket_notation/parser.rb', line 35

def input
  @input
end

Class Method Details

.validate(input) ⇒ Object

Performs basic validation of a string without executing the entire parse process. Returns true if validation is successful; raises an exception if not.



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
# File 'lib/bracket_notation/parser.rb', line 44

def self.validate(input)
  validation_error("parser input cannot be nil") if input.nil?
  validation_error("input string can't be empty") if input.length < 1
  validation_error("all opening brackets must have a label") if /\[\s*\[/ =~ input
  
  # Count the opening and closing brackets to make sure they're balanced
  chars = input.gsub(/[^\[\]]/, "").split(//)
  validation_error("opening and closing brackets must be balanced") if chars.length % 2 != 0
  
  open_count, close_count = 0, 0
  
  chars.each do |char|
    case char
      when '['
        open_count += 1
      when ']'
        close_count += 1
    end
    
    break if open_count < close_count
  end
  
  validation_error("opening and closing brackets must be properly nested") if open_count != close_count
  
  return true
end

Instance Method Details

#parseObject

Scans and evaluates the input string, returning an expression tree.



79
80
81
# File 'lib/bracket_notation/parser.rb', line 79

def parse
  Evaluator.new(Scanner.new(@input).scan).evaluate
end