Вы можете использовать конструкцию, которая уже нашла свое место в грамматиках синтаксического анализа (PEG), но также доступна в DCG.А именно отрицание цели DCG.В PEG восклицательный знак (!) С аргументом используется для отрицания, то есть!е.В DCG отрицание цели DCG выражается оператором (\ +), который уже используется для обычного отрицания как сбой в обычных предложениях и запросах Prolog.
Итак, давайте сначала объясним, как работает (\ +)в DCG.Если у вас есть производственное правило в форме:
A --> B, \+C, D.
, то это переводится в:
A(I,O) :- B(I,X), \+ C(X,_), D(X,O).
Это означает, что делается попытка разобрать цель C DCG, но на самом деле безиспользование списка ввода.Теперь это можно использовать для замены разреза, если это необходимо, и это дает немного больше декларативного ощущения.Чтобы объяснить идею, предположим, что с грамматикой без ws // 0.Таким образом, исходный набор выражений // 1 будет иметь вид:
expressions([E|Es]) --> expression(E), !, expressions(Es).
expressions([]) --> [].
С отрицанием мы можем превратить это в следующую форму вырезки:
expressions([E|Es]) --> expression(E), expressions(Es).
expressions([]) --> \+ expression(_).
К сожалению, приведенный выше вариантдовольно неэффективно, так как попытка разобрать выражение делается дважды.Один раз в первом правиле, а затем снова во втором правиле для отрицания.Но вы можете сделать следующее и проверить только отрицание начала выражения:
expressions([E|Es]) --> expression(E), expressions(Es).
expressions([]) --> \+ symbol(_), \+ number(_), \+ "(", \+ "'".
Если вы попробуете отрицание, вы увидите, что получаете сравнительно строгий анализатор.Это важно, если вы пытаетесь проанализировать максимальный префикс ввода и если вы хотите обнаружить некоторые ошибки.Попробуйте это:
?- phrase(expressions(X),"'",Y).
Вы должны получить ошибку в версии отрицания, которая проверяет первый символ выражения.В бесплатной и бесплатной версии вы получите пустой список.
Но вы также можете по-другому справляться с ошибками, я только сделал пример ошибки, чтобы немного осветить, как работает версия отрицания.
В других настройках, например, синтаксический анализатор CYK,можно сделать отрицание весьма эффективным, он может использовать информацию, уже размещенную на графике.
С наилучшими пожеланиями