Что такое "семантический предикат" в 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 }?, что приводит к тому, что парсер бросает aFailedPredicateExceptionвсякий раз, когда количество больше, чем 10 цифр.проверьте его с помощью следующих
ANTLRStringStream:// all equal or less than 10 digits ANTLRStringStream in = new ANTLRStringStream("1,23,1234567890");который не создает исключения, в то время как следующее делает thow исключение:
// '12345678901' is more than 10 digits ANTLRStringStream in = new ANTLRStringStream("1,23,12345678901");
2. Стробированные Семантические Предикаты
A закрытый семантический предикат похож на проверка семантического предиката, только закрытого типа версия выдает синтаксическую ошибку вместо
FailedPredicateException.синтаксис a закрытый семантический предикат - это:
{ /* a boolean expression in here */ }?=> RULEвместо того, чтобы решить вышеуказанную проблему с помощью закрытого типа предикаты для сопоставления чисел длиной до 10 цифр вы бы написали:
number @init { int N = 1; } : ( { N <= 10 }?=> Digit { N++; } )+ ;
Я всегда использовал краткую ссылку на ANTLR предикаты ВКЛ wincent.com как мой проводник.