Что такое "семантический предикат" в 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 как мой проводник.