не может создать неявный токен для строкового литерала в некомбинированной грамматике: - PullRequest
0 голосов
/ 29 ноября 2018

Это моя грамматика синтаксического анализатора XML:

attribute   :   Name '=' STRING ;

и лексер:

STRING      :   '"' ~[<"]* '"'
            |   '\'' ~[<']* '\''
            ;

Это работает, однако, когда я получаю бит STRING в своем коде C # с помощью:

context.STRING().ToString();

Я получаю текст, заключенный в кавычки, такие как: "привет", а не привет.Поэтому я пытаюсь изменить грамматику синтаксического анализатора на:

attribute   :   Name '=' '"' STRING ;

или

attribute   :   Name '="' STRING ;

и получаю ошибку: «не могу создать неявный токен для строкового литерала в некомбинированной грамматике»

Меня смущает вопрос, почему в грамматике синтаксического анализатора допускается «=», а не кавычки, и как изменить синтаксический анализатор для получения текста без кавычек.Кроме того, кажется, что лексер уже позаботился о том, чтобы избавиться от кавычек, поэтому я не понимаю, почему я все еще получаю их при разборе.

1 Ответ

0 голосов
/ 29 ноября 2018

Если у вас есть отдельные грамматики лексера и синтаксического анализатора, вам разрешается использовать строковые литералы в синтаксическом анализаторе тогда и только тогда, когда вы определили правило лексера, используя этот строковый литерал в лексере.В противном случае лексер никогда не выдаст токен, соответствующий этому литералу, поскольку лексер не знает, какие строковые литералы появляются или не появляются в синтаксическом анализаторе (это не относится к комбинированным грамматикам, поэтому в сообщении об ошибке указано «некомбинированная грамматика ").

Таким образом, вы можете использовать '=', но не '"', потому что у вас есть правило EQUALS: '=';, но нет правила DQUOTE: '"';.Но прежде чем вы добавите такое правило, давайте подумаем о том, что это будет делать и хотите ли вы этого (вы не хотите):

Если вы добавили такое правило (или использовали комбинированную грамматику, в которой выможно просто использовать '"' без него), правило attribute теперь будет соответствовать токену имени, за которым следует токен =, затем токен ", за которым следует строковый токен.Поскольку строковый токен уже содержит кавычки в его начале и конце, это будет выглядеть примерно так:

SomeName   =    "   "hello"
 Name     '='  '"'  STRING

Так что это не то, что вам нужно.Кроме того, это даже не сработает, даже если бы это было то, что вы хотели: первая кавычка в приведенном выше вводе не была бы распознана как '"' токен - вместо этого " " была бы распознана как строковый токен, тогда hello как Name и, наконец, " как '"' токен (потому что больше нет цитаты, которая бы соответствовала правилу STRING.

Так что это неправильное направление, и выне следует этого делать.


Если вам нужно получить содержимое строки без кавычек, то решение этой проблемы - не добавлять больше кавычек в грамматику. Вы должны просто использоватьSubstring в вашем коде C # для удаления первого и последнего символа из строки.

...