@@ -105,7 +105,7 @@ def get_entry(self, ps):
105105 return ast .GroupComment (comment .content )
106106 return None
107107
108- if ps .is_id_start () \
108+ if ps .is_message_id_start () \
109109 and (comment is None or isinstance (comment , ast .Comment )):
110110 return self .get_message (ps , comment )
111111
@@ -187,7 +187,7 @@ def skip_section(self, ps):
187187
188188 ps .skip_inline_ws ()
189189
190- self .get_symbol (ps )
190+ self .get_variant_name (ps )
191191
192192 ps .skip_inline_ws ()
193193
@@ -199,7 +199,7 @@ def skip_section(self, ps):
199199
200200 @with_span
201201 def get_message (self , ps , comment ):
202- id = self .get_identifier (ps )
202+ id = self .get_private_identifier (ps )
203203
204204 ps .skip_inline_ws ()
205205
@@ -225,7 +225,7 @@ def get_message(self, ps, comment):
225225 def get_attribute (self , ps ):
226226 ps .expect_char ('.' )
227227
228- key = self .get_identifier (ps )
228+ key = self .get_public_identifier (ps )
229229
230230 ps .skip_inline_ws ()
231231 ps .expect_char ('=' )
@@ -252,10 +252,17 @@ def get_attributes(self, ps):
252252 return attrs
253253
254254 @with_span
255- def get_identifier (self , ps ):
255+ def get_private_identifier (self , ps ):
256+ return self .get_identifier (ps , True )
257+
258+ @with_span
259+ def get_public_identifier (self , ps ):
260+ return self .get_identifier (ps , False )
261+
262+ def get_identifier (self , ps , allow_private ):
256263 name = ''
257264
258- name += ps .take_id_start ()
265+ name += ps .take_id_start (allow_private )
259266
260267 ch = ps .take_id_char ()
261268 while ch :
@@ -270,10 +277,11 @@ def get_variant_key(self, ps):
270277 if ch is None :
271278 raise ParseError ('E0013' )
272279
273- if ps .is_number_start ():
280+ cc = ord (ch )
281+ if ((cc >= 48 and cc <= 57 ) or cc == 45 ): # 0-9, -
274282 return self .get_number (ps )
275283
276- return self .get_symbol (ps )
284+ return self .get_variant_name (ps )
277285
278286 @with_span
279287 def get_variant (self , ps , has_default ):
@@ -323,19 +331,19 @@ def get_variants(self, ps):
323331 return variants
324332
325333 @with_span
326- def get_symbol (self , ps ):
334+ def get_variant_name (self , ps ):
327335 name = ''
328336
329- name += ps .take_id_start ()
337+ name += ps .take_id_start (False )
330338
331339 while True :
332- ch = ps .take_symb_char ()
340+ ch = ps .take_variant_name_char ()
333341 if ch :
334342 name += ch
335343 else :
336344 break
337345
338- return ast .Symbol (name .rstrip ())
346+ return ast .VariantName (name .rstrip ())
339347
340348 def get_digits (self , ps ):
341349 num = ''
@@ -455,22 +463,37 @@ def get_expression(self, ps):
455463
456464 if ps .current_is ('-' ):
457465 ps .peek ()
466+
458467 if not ps .current_peek_is ('>' ):
459468 ps .reset_peek ()
460- else :
461- ps .next ()
462- ps .next ()
469+ return selector
463470
464- ps .skip_inline_ws ()
471+ if isinstance (selector , ast .MessageReference ):
472+ raise ParseError ('E0016' )
465473
466- variants = self .get_variants (ps )
474+ if isinstance (selector , ast .AttributeExpression ) and \
475+ not selector .id .name .startswith ('-' ):
476+ raise ParseError ('E0018' )
467477
468- if len ( variants ) == 0 :
469- raise ParseError ('E0011 ' )
478+ if isinstance ( selector , ast . VariantExpression ) :
479+ raise ParseError ('E0017 ' )
470480
471- ps .expect_indent ()
481+ ps .next ()
482+ ps .next ()
472483
473- return ast .SelectExpression (selector , variants )
484+ ps .skip_inline_ws ()
485+
486+ variants = self .get_variants (ps )
487+
488+ if len (variants ) == 0 :
489+ raise ParseError ('E0011' )
490+
491+ ps .expect_indent ()
492+
493+ return ast .SelectExpression (selector , variants )
494+ elif isinstance (selector , ast .AttributeExpression ) and \
495+ selector .id .name .startswith ('-' ):
496+ raise ParseError ('E0019' )
474497
475498 return selector
476499
@@ -485,7 +508,7 @@ def get_selector_expression(self, ps):
485508
486509 if (ch == '.' ):
487510 ps .next ()
488- attr = self .get_identifier (ps )
511+ attr = self .get_public_identifier (ps )
489512 return ast .AttributeExpression (literal .id , attr )
490513
491514 if (ch == '[' ):
@@ -501,7 +524,7 @@ def get_selector_expression(self, ps):
501524
502525 ps .expect_char (')' )
503526
504- if not re .match ('^[A-Z_-]+ $' , literal .id .name ):
527+ if not re .match ('^[A-Z][A-Z_?-]* $' , literal .id .name ):
505528 raise ParseError ('E0008' )
506529
507530 return ast .CallExpression (
@@ -582,14 +605,16 @@ def get_literal(self, ps):
582605 if ch is None :
583606 raise ParseError ('E0014' )
584607
585- if ps .is_number_start ():
608+ if ch == '$' :
609+ ps .next ()
610+ name = self .get_public_identifier (ps )
611+ return ast .ExternalArgument (name )
612+ elif ps .is_message_id_start ():
613+ name = self .get_private_identifier (ps )
614+ return ast .MessageReference (name )
615+ elif ps .is_number_start ():
586616 return self .get_number (ps )
587617 elif ch == '"' :
588618 return self .get_string (ps )
589- elif ch == '$' :
590- ps .next ()
591- name = self .get_identifier (ps )
592- return ast .ExternalArgument (name )
593619
594- name = self .get_identifier (ps )
595- return ast .MessageReference (name )
620+ raise ParseError ('E0014' )
0 commit comments