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

Как реализовать обработку ошибок в ANTLR4

У меня есть следующая грамматика для разбора логических формул первого порядка, применяемых к графикам:

grammar Graph;


/*------------------------------------------------------------------
* PARSER RULES
*------------------------------------------------------------------*/

input
: 
formula EOF
;

formula
:
TRUE 
| FALSE 
| formula AND formula
| formula OR formula
| quantifier formula
| ST condition
;


condition
:
atom EQUALS QUOTE? (assignment | atom) QUOTE?
;

quantifier 
:
(FOREACH | EXISTS) variable IN domain
;

domain
:
(GRAPH_A | GRAPH_B)
;

atom
:
variable DOT property
;


variable
:   
(nodev | edgev)
;


nodev
:
(NODE | NODE1)
;

edgev
:
(EDGE | EDGE1)
;

property
:
(COLOR | VALUE)
;

assignment
:
(COLORTYPE | NUMBER)
;


/*------------------------------------------------------------------
* LEXER RULES
*------------------------------------------------------------------*/

TRUE : 'True' ;

FALSE : 'False' ;

AND : '&' ;

OR : '|' ;

ST : '->' ; 

EXISTS  : 'Exists' ;

FOREACH : 'Foreach' ;

NODE : 'node' ;

NODE1 : 'node1' ;

EDGE : 'edge' ;

EDGE1 : 'edge1' ;

IN : 'in' ;

GRAPH_A : 'GraphA' ;

GRAPH_B : 'GraphB' ;

EQUALS : '=' ;

DOT : '.' ;

COLOR : 'color' ;

VALUE : 'value' ;

NUMBER : ('0'..'9')+ (DOT ('0'..'9')+)? ;

QUOTE : '\'' ;

COLORTYPE : ('a'..'z')+ ;

WS : [ \t\r\n]+ -> skip ;

Я считаю, что это окончательная версия моей грамматики, поэтому теперь я хочу указать некоторую обработку ошибок для ввода. Проблема в том, что я не знаю как. Что я знаю, так это то, что после анализа ввода я могу выполнить итерацию по сгенерированному AST, и это место для добавления обработки ошибок.

Если синтаксический анализ не пройден, вернуть исключение синтаксического анализа; в противном случае я указал следующие случаи для возврата сообщения об ошибке.

  1. Не может быть 1 квантификатора, за которым следует -> condition (это элемент формулы), где условие равно atom=atom. Другими словами, если есть только quantifier, то condition должно быть равно atom EQUALS assignment.

  2. Если есть 2 квантификатора, первый должен начинаться с FOREACH

  3. Переменные в квантификаторах должны использоваться в операторе condition.

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

  5. Если есть 2 квантификатора, то к ним должны быть привязаны разные переменные.

Например, первый случай должен быть поднят, когда в качестве входных данных мы имеем

Exists node in GraphA -> node.color = node1.color 

потому что node1 не указано в левой части выражения.

Примером для второго случая может быть следующий ввод

Exists node in GraphA Exists node1 in GraphB -> node.color = node1.color

Итак, мой вопрос: нужно ли мне реализовать всю проверку ошибок в сгенерированном дереве синтаксического анализа или я могу указать некоторые из них в грамматике, используя некоторый код Java. Если обработка ошибок должна происходить после анализа ввода, какие функции ANTLR 4 я могу использовать для реализации случаев ошибок? Любая помощь или совет будут высоко оценены!


  • Я думаю, что класс visitor сможет решить мои проблемы. Когда я просматриваю дерево синтаксического анализа, я добавляю интересующие меня элементы в структуру данных (вероятно, HashMap или что-то в этом роде), а затем применяю необходимую логику. Я в правильном направлении или мне не хватает фундаментальных знаний об ANTLR? 07.02.2014

Ответы:


1

Вероятно, вы захотите реализовать эти семантические проверки в слушателе в сочетании с посетителями-помощниками. Вот несколько примеров.

Правило: переменные в quantifier должны использоваться в condition

Реализация:

  1. Создайте посетителя, который возвращает переменные, используемые указанным узлом дерева синтаксического анализа. Вы захотите переопределить defaultResult() и aggregateResult(T, T), чтобы сделать большую часть работы за вас, а затем переопределить visitNodev и visitEdgev для обработки конкретных используемых переменных.
  2. В вашем слушателе переопределите метод enterFormula. В этом методе, если ctx.quantifier() не равно нулю, используйте посетителя для получения списка переменных, объявленных в ctx.quantifier(), и списка переменных, используемых в ctx.formula().
  3. Сообщите об ошибке соответствующим образом на основе двух результатов.

Правило: если есть 2 квантификатора, то они должны иметь разные переменные, связанные с ними.

Реализация:

  1. Начните с посетителя, описанного в шаге 1 реализации предыдущего правила.
  2. В вашем слушателе переопределите метод enterFormula. В методе, если ctx.quantifier() не равно нулю, вам нужно получить коллекцию всех других экземпляров QuantifierContext под деревом, возвращаемым ctx.formula(). Вы можете сделать это, вызвав XPath.findAll(ctx.formula(), "//quantifier", parser).
  3. Используйте посетитель, описанный выше, чтобы собрать список переменных, объявленных в каждом из связанных экземпляров QuantifierContext. Если какой-либо из наборов перекрывается, сообщите об ошибке соответствующим образом.

Правило: если есть 2 квантификатора, первый должен начинаться с FOREACH

Реализация:

Используйте шаблон слушателя, описанный в предыдущем шаге, чтобы найти случаи, когда формула содержит более одного quantifier. Если первая из этих формул имеет ctx.quantifier().FOREACH() == null, выдается соответствующая ошибка.

Правило: не может быть более двух квантификаторов...

Реализация:

Обновите реализацию второго правила выше, чтобы сообщить об ошибке, если XPath.findAll возвращает более одного QuantifierContext в formula для quantifier.

Правило: ограничение условия квантификатора

Реализация:

Сначала создайте ParseTreePattern. объект.

String patternString = "<quantifier> -> <condition>";
ParseTreePattern pattern =
    parser.compileParseTreePattern(patternString, GraphParser.RULE_formula);

Затем найдите все экземпляры этого шаблона в дереве синтаксического анализа.

List<ParseTreeMatch> matches = pattern.findAll(tree, "//formula");

Затем проверить совпадения довольно просто.

for (ParseTreeMatch match : matches) {
  ConditionContext condition = (ConditionContext)match.get("condition");
  if (condition.assignment() == null) {
    // TODO: report error here
  }
}
06.02.2014
  • Отличный ответ. Не могли бы вы просто объяснить мне, как правильно использовать XPath. То, что я делаю в enterFormula(), это Collection<ParseTree> q = XPath.findAll(ctx,"//quantifer",parser);, где ctx имеет тип FormulaContext, и каждый раз я получаю NullPointerException. У вас есть идеи, почему это происходит? 09.02.2014
  • Вы имели в виду quantifier, а не quantifer. Вы должны создать задачу без GitHub, чтобы мы могли исправить это поведение (с лучшим сообщением об ошибке) для следующего выпуска: github.com/antlr/antlr4/issues 09.02.2014
  • Сделаю. Есть ли другой способ запросить FormulaContext, чтобы получить количество элементов Quantifier? 09.02.2014
  • Новые материалы

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

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

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

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

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

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

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