Что такое "семантический предикат" в ANTLR?
Что это семантический предикат в ANTLR?
2 ответов
ANTLR 4
для предикатов в ANTLR 4, проверьте эти стекпереполнения Q&это:
ANTLR 3
A семантический предикат - это способ применения дополнительных (семантических) правил к грамматике действия, используя простые код.
существует 3 типа семантических предикатов:
- проверка семантические предикаты;
- закрытого типа семантические предикаты;
- устранение неоднозначностей семантические предикаты.
пример грамматики
предположим, у вас есть блок текста, состоящий только из чисел, разделенных
запятая, игнорируя любые свободное пространство. Вы хотели бы проанализировать этот ввод
уверен, что цифры не более 3 цифр "длинные" (не более 999). Следующий
грамматика (Numbers.g
) сделал бы такую вещь:
grammar Numbers;
// entry point of this parser: it parses an input string consisting of at least
// one number, optionally followed by zero or more comma's and numbers
parse
: number (',' number)* EOF
;
// matches a number that is between 1 and 3 digits long
number
: Digit Digit Digit
| Digit Digit
| Digit
;
// matches a single digit
Digit
: '0'..'9'
;
// ignore spaces
WhiteSpace
: (' ' | '\t' | '\r' | '\n') {skip();}
;
тестирование
грамматика может быть протестирована со следующим классом:
import org.antlr.runtime.*;
public class Main {
public static void main(String[] args) throws Exception {
ANTLRStringStream in = new ANTLRStringStream("123, 456, 7 , 89");
NumbersLexer lexer = new NumbersLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
NumbersParser parser = new NumbersParser(tokens);
parser.parse();
}
}
проверьте его, генерируя лексер и парсер, компилируя все .java
файлы и
под управлением Main
класс:
java -cp antlr-3.2.jar org.antlr.Tool Numbers.g javac -cp antlr-3.2.jar *.java java -cp .:antlr-3.2.jar Main
при этом ничего не печатается к консоли, которая указывает, что ничего сорваться. Попробуйте изменить:
ANTLRStringStream in = new ANTLRStringStream("123, 456, 7 , 89");
в:
ANTLRStringStream in = new ANTLRStringStream("123, 456, 7777 , 89");
и повторите тест: вы увидите ошибку, появляющуюся на консоли сразу после строки 777
.
Семантические Предикаты
это подводит нас к семантическому предикату. Допустим, вы хотите разобрать числа от 1 до 10 цифр. Правило вроде:
number
: Digit Digit Digit Digit Digit Digit Digit Digit Digit Digit
| Digit Digit Digit Digit Digit Digit Digit Digit Digit
/* ... */
| Digit Digit Digit
| Digit Digit
| Digit
;
станет громоздким. Семантический предикаты могут помочь упростить этот тип правил.
1. Проверка Семантических Предикатов
A проверка семантического предиката ничего больше, чем блок кода, за которым следует вопросительный знак:
RULE { /* a boolean expression in here */ }?
чтобы решить проблему, с помощью проверка
семантический предикат, изменить number
правило в грамматике в:
number
@init { int N = 0; }
: (Digit { N++; } )+ { N <= 10 }?
;
запчасти { int N = 0; }
и { N++; }
простые Операторы Java, которые
первый инициализируется, когда парсер "входит" в number
правило. Действительность
сказуемое:{ N <= 10 }?
, что заставляет парсер бросать
FailedPredicateException
когда число длиннее 10 цифр.
проверьте его, используя следующее ANTLRStringStream
:
// all equal or less than 10 digits
ANTLRStringStream in = new ANTLRStringStream("1,23,1234567890");
который не создает исключения, в то время как следующее делает исключение:
// '12345678901' is more than 10 digits
ANTLRStringStream in = new ANTLRStringStream("1,23,12345678901");
2. Стробированные Семантические Предикаты
A закрытый семантический предикат похож на проверка семантического предиката,
только закрытого типа версия выдает синтаксическую ошибку вместо FailedPredicateException
.
синтаксис закрытый семантический предикат - это:
{ /* a boolean expression in here */ }?=> RULE
вместо этого решить вышеуказанную проблему с помощью закрытого типа предикаты для сопоставления чисел длиной до 10 цифр вы напишете:
number
@init { int N = 1; }
: ( { N <= 10 }?=> Digit { N++; } )+
;
Я всегда использовал краткую ссылку на предикаты ANTLR on wincent.com как мой проводник.