Nano Hash - криптовалюты, майнинг, программирование

Посторонняя ошибка ввода при использовании действий правила лексера и команд лексера

Я вижу ошибку "посторонний ввод" с вводом "\ aa a" и следующей грамматикой:

Круто.g4

grammar Cool;
import Lex;

expr
   : STR_CONST # str_const
   ;

Lex.g4

lexer grammar Lex;

@lexer::members {
  public static boolean initial = true;
  public static boolean inString = false;
  public static boolean inStringEscape = false;
}

BEGINSTRING: '"' {initial}? {
  inString = true;
  initial = false;
  System.out.println("Entering string");
} -> more;

INSTRINGSTARTESCAPE: '\\' {inString && !inStringEscape}? {
  inStringEscape = true;
  System.out.println("The next character will be escaped!");
} -> more;

INSTRINGAFTERESCAPE: ~[\n] {inString && inStringEscape}? {
  inStringEscape = false;
  System.out.println("Escaped a character.");
} -> more;

INSTRINGOTHER: (~[\n\\"])+ {inString && !inStringEscape}? {
  System.out.println("Consumed some other characters in the string!");
} -> more;

STR_CONST: '"' {inString && !inStringEscape}? {
  inString = false;
  initial = true;
  System.out.println("Exiting string");
};

WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines

ID:  [a-z][_A-Za-z0-9]*;

Вот результат:

$ grun Cool expr -tree
"\aa a"
Entering string
The next character will be escaped!
Escaped a character.
Consumed some other characters in the string!
Exiting string
line 1:0 extraneous input '"\aa' expecting STR_CONST
(expr "\aa  a")

Интересно, что если я удалю правило идентификатора, antlr нормально разбирает ввод. Вот результат, когда я удаляю правило идентификатора:

$ grun Cool expr -tree
"\aa a"
Entering string
The next character will be escaped!
Escaped a character.
Consumed some other characters in the string!
Exiting string
(expr "\aa a")

Есть идеи, что может происходить? Почему antlr выдает ошибку, если ID является одним из правил лексера?

03.06.2019

Ответы:


1

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

Я рекомендую другой (и гораздо более простой) подход:

STR_CONST: '"' ('\\"' | .)*? '"';

Затем на семантической фазе, когда вы публикуете свое дерево синтаксического анализа, исследуйте совпавший текст, чтобы найти escape-последовательности. Преобразуйте их в настоящие символы и распечатайте хорошее сообщение об ошибке, если была обнаружена недопустимая escape-последовательность (что вы не можете сделать при попытке сопоставить escape-последовательности в лексере).

03.06.2019
  • Привет Майк. Я решил проблему с помощью STR_CONST: '' (ESC |.) *? ''; фрагмент ESC: '\\' | '\\\\'; Но я до сих пор не понимаю, почему antlr выдает ошибку, когда ID является одним из правил Lexer. Это ожидаемое поведение в antlr? Боковое примечание: вы упомянули о печати полученных токенов. Как мне это сделать? Чем она отличается от команды grun Cool expr -tree? 03.06.2019
  • Не могу понять, почему правило ID дает такой удивительный эффект. Это нужно будет детально отладить. Для печати токенов: я никогда не использовал grun, поэтому я не могу сказать, позволяет ли он это сделать, но в коде с вашим сгенерированным лексером вы можете вызвать fill() для анализа всех токенов, а затем перебрать их и распечатать их текстовое представление. Это покажет вам, какие типы обнаружил лексер и соответствуют ли они вашим ожиданиям. 04.06.2019

  • 2

    Копирование ответа, полученного мной от @sharwell, на GitHub.

    "Ваше ID правило не предопределено, поэтому оно соответствует aa после \ (aa длиннее, чем a, которому соответствует INSTRINGAFTERESCAPE, поэтому оно предпочтительнее, даже если оно находится позже в грамматике). Если вы добавите println к WS и ID, вы увидите странное поведение на выходе ".

    17.10.2019
    Новые материалы

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

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..