Class: Babelfish::Phrase::Parser

Inherits:
ParserBase show all
Defined in:
lib/babelfish/phrase/parser.rb

Overview

Babelfish syntax parser.

Constant Summary collapse

LITERAL_MODE =
'Literal'.freeze
VARIABLE_MODE =
'Variable'.freeze
PLURALS_MODE =
'Plurals'.freeze
VARIABLE_RE =
/^[a-zA-Z0-9_\.]+$/
AST_MAP =
{
    LITERAL_MODE  => Babelfish::Phrase::Literal,
    VARIABLE_MODE => Babelfish::Phrase::Variable,
    PLURALS_MODE  => Babelfish::Phrase::PluralForms,
}

Class Attribute Summary collapse

Instance Attribute Summary collapse

Attributes inherited from ParserBase

#index, #length, #phrase, #piece, #prev

Instance Method Summary collapse

Methods inherited from ParserBase

#add_to_piece, #backward, #char, #next_char, #throw, #to_next_char

Constructor Details

#initialize(phrase = nil, locale = nil) ⇒ Parser

Instantiates parser.



27
28
29
30
31
# File 'lib/babelfish/phrase/parser.rb', line 27

def initialize( phrase = nil, locale = nil )
    super( phrase )
    init( phrase )  unless phrase.nil?
    self.locale = locale  if locale
end

Class Attribute Details

.plurals_parserObject

Returns the value of attribute plurals_parser.



57
58
59
# File 'lib/babelfish/phrase/parser.rb', line 57

def plurals_parser
  @plurals_parser
end

Instance Attribute Details

#escapeObject

Returns the value of attribute escape.



13
14
15
# File 'lib/babelfish/phrase/parser.rb', line 13

def escape
  @escape
end

#localeObject

Returns the value of attribute locale.



13
14
15
# File 'lib/babelfish/phrase/parser.rb', line 13

def locale
  @locale
end

#modeObject

Returns the value of attribute mode.



13
14
15
# File 'lib/babelfish/phrase/parser.rb', line 13

def mode
  @mode
end

#pf0Object

Returns the value of attribute pf0.



13
14
15
# File 'lib/babelfish/phrase/parser.rb', line 13

def pf0
  @pf0
end

#piecesObject

Returns the value of attribute pieces.



13
14
15
# File 'lib/babelfish/phrase/parser.rb', line 13

def pieces
  @pieces
end

Instance Method Details

#escape?Boolean

Returns:

  • (Boolean)


64
65
66
# File 'lib/babelfish/phrase/parser.rb', line 64

def escape?
    !! self.escape
end

#finalize_modeObject

Finalizes all operations after phrase end.



42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/babelfish/phrase/parser.rb', line 42

def finalize_mode
    case mode
    when LITERAL_MODE
        pieces.push( AST_MAP[LITERAL_MODE].new( text: piece ) ) if !piece.empty? || pieces.size == 0;
    when VARIABLE_MODE
        throw( "Variable definition not ended with \"}\": " + piece )
    when PLURALS_MODE
        throw( "Plural forms definition not ended with \"))\": " + piece )  if pf0.nil?
        pieces.push( AST_MAP[PLURALS_MODE].new( forms: pf0, name: piece, locale: locale ) )
    else
        throw( "Logic broken, unknown parser mode: " + mode );
    end
end

#init(phrase) ⇒ Object

Initializes parser. Should not be called directly.



34
35
36
37
38
39
# File 'lib/babelfish/phrase/parser.rb', line 34

def init( phrase )
    super( phrase )
    self.mode = LITERAL_MODE
    self.pieces = []
    self.pf0 = nil # plural forms without name yet
end

#parse(phrase = nil, locale = nil) ⇒ Object

Parses specified phrase.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/babelfish/phrase/parser.rb', line 69

def parse( phrase = nil, locale = nil )
    super( phrase )
    self.locale = locale  unless locale.nil?

    while true
        _char = to_next_char

        if _char.empty?
            finalize_mode
            return pieces
        end

        case mode
        when LITERAL_MODE
            if escape?
                add_to_piece( _char )
                self.escape = false
                next
            end

            if _char == "\\"
                self.escape = true
                next
            end

            if _char == '#' && next_char == '{'
                unless piece.empty?
                    pieces.push( AST_MAP[LITERAL_MODE].new( text: piece ) )
                    self.piece = ''
                end
                self.to_next_char # skip "{"
                self.mode = VARIABLE_MODE
                next
            end

            if _char == '(' && next_char == '('
                unless piece.empty?
                    pieces.push( AST_MAP[LITERAL_MODE].new( text: piece ) )
                    self.piece = ''
                end
                to_next_char # skip second "("
                self.mode = PLURALS_MODE
                next
            end

        when VARIABLE_MODE
            if escape?
                add_to_piece( _char )
                self.escape = false
                next
            end

            if _char == "\\"
                self.escape = true
                next
            end

            if _char == '}'
                name = piece.strip
                if name.empty?
                    throw( "No variable name given." );
                end
                if name !~ VARIABLE_RE
                    throw( "Variable name doesn't meet conditions: #{name}." );
                end
                pieces.push( AST_MAP[VARIABLE_MODE].new( name: name ) )
                self.piece = ''
                self.mode = LITERAL_MODE
                next
            end

        when PLURALS_MODE
            unless pf0.nil?
                if _char =~ VARIABLE_RE && (_char != '.' || next_char =~ VARIABLE_RE)
                    add_to_piece( _char )
                    next
                else
                    pieces.push( AST_MAP[PLURALS_MODE].new( forms: pf0, name: piece, locale:locale ) )
                    self.pf0 = nil
                    self.mode = LITERAL_MODE
                    self.piece = ''
                    backward
                    next
                end
            end
            if _char == ')' && next_char == ')'
                self.pf0 = plurals_parser.parse( piece )
                self.piece = ''
                to_next_char # skip second ")"
                if next_char == ':'
                    to_next_char # skip ":"
                    next
                end
                pieces.push( AST_MAP[PLURALS_MODE].new( forms: pf0, name: 'count', locale: locale ) )
                self.pf0 = nil
                self.mode = LITERAL_MODE
                next
            end
        end
        add_to_piece( _char )
    end # while ( 1 )
end

#plurals_parserObject



60
61
62
# File 'lib/babelfish/phrase/parser.rb', line 60

def plurals_parser
    Parser.plurals_parser ||= Babelfish::Phrase::PluralFormsParser.new
end