Я пишу грамматику для формата сериализации, подобного YAML. Я использую парсер LALR. При синтаксическом анализе скаляров я столкнулся с препятствием. Скаляр может быть строкой или числом (давайте оставим его простым и сделаем только десятичными или плавающими). Вот что у меня есть до сих пор, я сохранил только то, что имеет значение здесь:
pair: pair_key ":" _value
_value: scalar | collection
scalar : (string | number) _NL+
string : WORD+
number : DECIMAL | FLOAT
DECIMAL : /0|[1-9]\d*/i
FLOAT: /((\d+\.\d*|\.\d+)(e[-+]?\d+)?|\d+(e[-+]?\d+))/i
WORD: /[^-:#()\[\]{}\n\s]+/
// NEWLINE
_NL: /(\r?\n[\t ]*)+/
%import common.WS_INLINE
%ignore WS_INLINE
Строка - это одно или несколько слов. WORD может содержать любые символы, кроме тех, которые я ввел в инвертированный набор регулярного выражения WORD. Я хочу, чтобы мои строки могли содержать числа и по-прежнему анализироваться как строки, поэтому в моем отрицательном наборе для WORD нет цифр. Проблема заключается в том, что строка начинается с числа как такового:
test_strings = """
a : 28 should be parsed as string
b : 28
"""
Парсер не может выбрать между анализом числа или слова, когда видит 28 в начале.
Вот что Я получаю:
top_map
pair
pair_key
string a
scalar
string
28
should
be
parsed
as
string
pair
pair_key
string b
scalar
string 28
Ожидается:
top_map
pair
pair_key
string a
scalar
string
28
should
be
parsed
as
string
pair
pair_key
string b
scalar
number 28
Как мне go разрешить эту неоднозначность? Есть ли способ сделать это, используя только грамматику? Обратите внимание, что я не хочу, чтобы мои строки были окружены кавычками или другими символами, чтобы их можно было идентифицировать.
Изменить
Я решил проблему, используя более высокий приоритет в моем числовом правиле как таковом:
string : number WORD+ | WORD+
number.2 : DECIMAL | FLOAT
DECIMAL.2 : /0|[1-9]\d*/i
FLOAT.2: /((\d+\.\d*|\.\d+)(e[-+]?\d+)?|\d+(e[-+]?\d+))/i
WORD: /[^-:#()\[\]{}\n\s]+/
Таким образом, число будет анализируется как число, а не как СЛОВО. И строки, начинающиеся с цифр, должны иметь СЛОВА, идущие после. Таким образом, в этой модифицированной версии нет строки, которая представляет собой просто число.