Грамматика для JSON-подобного языка

Я пытаюсь разработать грамматику для языка, подобного JSON. Основные отличия заключаются в том, что имена свойств не нужно заключать в двойные кавычки (хотя они могут быть), и что числа являются только целыми числами (без чисел с плавающей запятой).

Вот один из примеров:

{
  "property1": "string value",
  property2: 321,
  arr: [1,2,3]
}

Это моя (попытка) грамматика:

grammar Command;

command: object;

object:   '{' pair (',' pair)* '}' ;

pair: name ':' value ;

name
   : '"' ID '"'
   | ID
   ;

value
    :   string
    |   integer
    |   object
    |   array
    |   bool
    ;

array: '[' value (',' value)* ']' ;

string: STRING ;

integer
      : ZERO
      | NONZERO 
      ;

bool
   : 'true' 
   | 'false' 
   ;

ID : [a-zA-Z0-9_]+ ;
STRING: '"' (ESC | .)*? '"' ;
fragment ESC: '\\"' | '\\\\' ;

ZERO: '0' ;
NONZERO: '-'? [1-9] [0-9]* ; 
WS  :   [ \t\n\r]+ -> skip ;

Однако, пытаясь запустить TestRig на входе моего примера, я получаю

line 2:2 no viable alternative at input '"property"'
line 3:10 no viable alternative at input '321'
line 4:8 no viable alternative at input '1'
line 4:10 no viable alternative at input '2'
line 4:12 no viable alternative at input '3'

Любые идеи, где я ошибаюсь?

Спасибо за ваше время!

Туомас


person tuope    schedule 18.04.2013    source источник
comment
Похоже, ваше правило name содержит пробелы между кавычками и идентификатором.   -  person MichaelJCox    schedule 18.04.2013
comment
json - это современный язык? Я думал, что это формат :-)   -  person Marco van de Voort    schedule 18.04.2013
comment
Марко, простите за неточность. :-)   -  person tuope    schedule 18.04.2013


Ответы (1)


  • Лексер создает один токен STRING для "property", поэтому вам следует настроить правило name:

    name : STRING | ID;
    
  • Вам нужно переместить правило ID после ZERO и NONZERO. Поскольку ваши числа также соответствуют правилу лексера ID, им будет присвоен тип токена в соответствии с первым правилом, появившимся в грамматике. Вы хотите, чтобы первое правило было ZERO или NONZERO, где сейчас ID. (Поскольку все ваши числа в настоящее время приводят к токенам ID, а ID не допускается как value, вы получаете синтаксические ошибки.)

person Sam Harwell    schedule 18.04.2013
comment
Большое спасибо! Ваш совет помог мне решить проблему. Забавно, я читаю The Definitive Antlr4 Reference и забыл, что порядок токенов имеет значение. :-) - person tuope; 18.04.2013