{:error, {:undefined, :standard_syntax_parser, ['синтаксическая ошибка до: ', []]}}

Поэтому я пытаюсь использовать yecc.

Terminals string string_delimeter.

Nonterminals value string_content.

Rootsymbol value.

value -> string : extract_value('$1').

value -> string_delimeter string_content string_delimeter : '$2'.
string_content -> value string_content : ['$1' | '$2'].
string_content -> value : '$1'.

Erlang code.

extract_value({_, Value}) -> Value.

Для ввода:

[string_delimeter: '\'', string: 'test', string_delimeter: '\'']

я получил

{:error, {:undefined, :standard_syntax_parser, ['syntax error before: ', []]}}

Если я удалю любой (левый или правый) string_delimeter, окружающий string_content:

value -> string_delimeter string_content string_delimeter : '$2'.

value -> string_delimeter string_content : '$2'.

для

[string_delimeter: '\'', string: 'test']

он возвращается

{:ok, 'test'}

Я не очень понимаю это поведение, в чем проблема?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
129
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

For the input:

[string_delimeter: '\'', string: 'test', string_delimeter: '\'']

Я думаю, что вы запутались (или, может быть, это я!). yecc ожидает список токенов, где токен представляет собой кортеж из 2 или 3 элементов. Из документы yecc:

The user should implement a scanner that segments the input text, and turns it into one or more lists of tokens. Each token should be a tuple containing information about syntactic category, position in the text (e.g. line number), and the actual terminal symbol found in the text: {Category, LineNumber, Symbol}.

If a terminal symbol is the only member of a category, and the symbol name is identical to the category name, the token format may be {Symbol, LineNumber}...

Вот пример того, что ожидает yecc:

[
     {'[',1},
     {atom,1,foo},
     {',',1},
     {'[',1},
     {int,1,1},
     {']',1},
     {',',1},
     {'[',1},
     {atom,1,bar},
     {',',1},
     {'[',1},
     {int,1,2},
     {',',1},
     {int,1,3}, 
     {']',1},
     {']',1},
     {']',1}
]

Вы можете реализовать такой сканер с помощью leex, а затем передать результат вашему синтаксическому анализатору yecc.

Небольшой совет: вы никогда не должны публиковать вопрос, описывающий, как вы запускали свой код — это просто большая трата времени. Вместо этого скопируйте и вставьте точные команды, которые вы выполнили, а также результат, полученный этими командами. Все, что вам нужно сказать, это:

  1. This is what I tried:

[Your code here]

  1. Here is the output:

[all commands you ran and the output here]

  1. This is the output I expect/want, or Wtf??!! is going on.

[expected/desired output here]

Я использую leex и добавил TokenLine, без разницы. Из того, что я вижу, я не могу сделать: token_1 token_2 token_1 -> и т. д. Облом, как я мог справиться с foobarfoo, когда я хочу foo.

user8217653 22.07.2019 13:08

Ах хорошо. Вы используете elixir, хотя теги в вашем вопросе говорят, что вы используете erlang. Я могу заставить работать более простую версию вашего парсера:

string_parser.yrl:

Nonterminals the_string content.
Terminals '\'' string.
Rootsymbol the_string.

the_string -> '\'' content '\'' : '$2'.

%I guess the atom :string has to be the first element of the tuple
%returned by '$2' in previous line:
content -> string : extract_value('$1')

Erlang code.

extract_value({_, _, Value}) -> Value.

В иксе:

iex(1)> :yecc.file('string_parser.yrl')  
{:ok, 'string_parser.erl'}

iex(2)> c("string_parser.erl")
[:string_parser]

iex(3)> :string_parser.parse([{:"'", 1}, {:string, 1, "hello"}, {:"'", 1}])
{:ok, "hello"}

Но я не могу заставить рекурсивное определение работать.

Хорошо, я приближаюсь:

string_parser.yrl:

Nonterminals string interior_strings interior_string.
Terminals left_delim right_delim result.
Rootsymbol string.

string -> left_delim interior_strings right_delim : '$2'.
string -> left_delim right_delim : "".

interior_strings -> interior_string : ['$1'].
interior_strings -> interior_string interior_strings : ['$1' | '$2'].

interior_string -> result : extract_value('$1').
interior_string -> string : '$1'.

Erlang code.

extract_value({_, _, Value}) -> Value.

В иксе:

iex(49)> :yecc.file('string_parser.yrl')
{:ok, 'string_parser.erl'}

iex(50)> c("string_parser.erl")
[:string_parser]    

iex(51)> :string_parser.parse([{:left_delim, 1}, {:result, 1, "hello"}, {:left_delim, 1}, {:result, 1, "goodbye"}, {:right_delim, 1}, {:right_delim, 1}])
{:ok, ["hello", ["goodbye"]]}

iex(53)> 

На данный момент я не знаю, почему взорванные скобки вокруг "goodbye".

Успех!

string_parser.yrl:

Nonterminals string interior_strings interior_string.
Terminals left_delim right_delim result.
Rootsymbol string.

string -> left_delim interior_strings right_delim : '$2'.
string -> left_delim right_delim : "".

interior_strings -> left_delim interior_string right_delim: ['$2'].
interior_strings -> interior_string interior_strings : ['$1' | '$2'].

interior_string -> result : extract_value('$1').
interior_string -> string : '$1'.

Erlang code.

extract_value({_, _, Value}) -> Value.

В иксе:

iex(53)> :yecc.file('string_parser.yrl') 
{:ok, 'string_parser.erl'}  

iex(54)> c("string_parser.erl")
[:string_parser] 

iex(55)> :string_parser.parse([{:left_delim, 1}, {:result, 1, "hello"}, {:left_delim, 1}, {:result, 1, "goodbye"}, {:right_delim, 1}, {:right_delim, 1}])
{:ok, ["hello", "goodbye"]}

Единственное, что я до сих пор не могу сделать, это если я явно укажу '\'' для разделителя:

Nonterminals string interior_strings interior_string.
Terminals '\'' result.
Rootsymbol string.
Endsymbol '$end'.

string -> '\'' interior_strings '\'' : '$2'.
string -> '\'' '\'' : "".

interior_strings -> '\'' interior_string '\'': ['$2'].
interior_strings -> interior_string interior_strings : ['$1' | '$2'].

interior_string -> result : extract_value('$1').
interior_string -> string : '$1'.

Erlang code.

extract_value({_, _, Value}) -> Value.

В иксе:

iex(3)> :string_parser.parse([{:"'", 1}, {:result, 1, "hello"}, 
{:"'", 1}, {:result, 1, "goodbye"}, {:"'", 1}, {:"'", 1}, {:"$end", 1}])  

{:error, {1, :string_parser, ['syntax error before: ', []]}}

Слишком неприятно работать с такими ужасными сообщениями об ошибках. Синтаксическая ошибка перед пустым списком []??! Где пустой список в списке токенов?

Я думал, что добавление последнего кортежа: {:"$end", 1} может сработать, но не повезло. Та же ошибка.

Я могу заставить string_parser работать, если использую буквальные скобки в качестве разделителей:

string_parser.yrl:

Nonterminals string interior_strings interior_string.
Terminals '[' ']' content.
Rootsymbol string.

string -> '[' interior_strings ']' : '$2'.
string -> '[' ']' : "".

interior_strings -> '[' interior_string ']' : ['$2'].
interior_strings -> interior_string interior_strings : ['$1' | '$2'].

interior_string -> content : extract_content('$1').
interior_string -> string : '$1'.

Erlang code.

extract_content({_, _, Content}) -> Content.

В иксе:

iex(11)> :yecc.file('string_parser.yrl')
{:ok, 'string_parser.erl'}  

iex(12)> c("string_parser.erl") 
[:string_parser]    

iex(13)> :string_parser.parse([{:"[", 1}, {:content, 1, "hello"}, {:"[", 1}, {:content, 1, "goodbye"}, {:"]", 1}, {:"]", 1}])

{:ok, ["hello", "goodbye"]}
iex(14)> 

Я попытался написать string_parser в erlang и получил ту же ошибку. Файлы .yrl не имеют синтаксиса erlang, поэтому все, что анализирует файлы .yrl, похоже, не может разобрать атом с одной кавычкой: '\''.

Ответ принят как подходящий

Я не понял, почему это проблема в yecc: токен_1 токен_2 токен_1 Я действительно хотел бы знать, но у меня есть способ обойти это:

Terminals string string_delimeter whitespace.


Nonterminals value string_content.


Rootsymbol value.

value -> string : extract_value('$1').

value -> string_delimeter string_content : '$2'.
string_content -> string_content string_delimeter : '$1'.
string_content -> value whitespace string_content : ['$1' | '$3'].
string_content -> value : ['$1'].

Erlang code.

extract_value({_, Value}) -> Value.
это проблема в yecc: [token1, token2, token1] -- Эй, ты прав! Я думал, что проблема была только в одинарных кавычках. Я не могу разобрать следующее: :string_parser.parse([{:a, 1}, {:content, 1, "hello"}, {:a, 1}]) => {:error, {1, :string_parser, ['syntax error before: ', []]}}. Та же ошибка, что и с одинарной кавычкой.
7stud 22.07.2019 22:51

Но... я могу разобрать [token1, token2, token1] -- даже с одинарными кавычками для token1 -- если я напишу нерекурсивный парсер: :string_parser.parse([{:"'", 1}, {:content, 1, "hello"}, {:"'", 1}]) => {:ok, "hello"}

7stud 22.07.2019 23:00

Другие вопросы по теме