lib/twitter_cldr/transforms/conversions/parser.rb
# encoding: UTF-8
# Copyright 2012 Twitter, Inc
# http://www.apache.org/licenses/LICENSE-2.0
module TwitterCldr
module Transforms
module Conversions
class Parser < TwitterCldr::Parsers::Parser
private
def do_parse(options)
first_side = side
direction = get_direction_from(current_token)
next_token(:direction)
second_side = side
first_side, second_side = rearrange_sides(
direction, first_side, second_side
)
ConversionRule.new(
direction, first_side, second_side,
options[:original_rule_text],
options[:index]
)
end
def rearrange_sides(direction, first_side, second_side)
case direction
when :backward
[second_side, first_side]
else
[first_side, second_side]
end
end
# a { b | c } d <> e { f | g } h ;
def side
prev_cluster = next_token_cluster
before_context = nil
after_context = nil
key = nil
cursor_offset = 0
until current_token.type == :direction || current_token.type == :semicolon
case current_token.type
when :before_context
before_context = prev_cluster
next_token(:before_context)
prev_cluster = next_token_cluster
when :cursor
next_token(:cursor)
cur_cluster = next_token_cluster
key = prev_cluster + cur_cluster
prev_cluster = cur_cluster
cursor_offset = -cur_cluster.size
when :after_context
next_token(:after_context)
after_context = next_token_cluster
end
end
key ||= prev_cluster
Side.new(
join_values(before_context),
key,
join_values(after_context),
cursor_offset
)
end
def join_values(tokens)
Array(tokens).map(&:value).join
end
def next_token_cluster
tokens = []
until is_operator?(current_token) || current_token.type == :semicolon
tokens << current_token
next_token(current_token.type)
end
tokens
end
def is_operator?(token)
case token.type
when :direction, :after_context, :before_context, :cursor
true
else
false
end
end
def get_direction_from(token)
case token.value
when '>'
:forward
when '<'
:backward
when '<>'
:bidirectional
end
end
end
end
end
end