#antlr #antlr4
#antlr #antlr4
Вопрос:
Я пытаюсь использовать ANLTR4 для анализа 2 типов выражений:
- парные выражения представляют собой пару целых или чисел с плавающей запятой, например
(1,2)
или(1.0 , 2.0)
. - отдельные выражения представляют собой одно целое
(1)
число.
Я разработал свою грамматику, как показано ниже, но
- Если я напишу
INT
раньшеNUM
, выражения пары с целыми числами, например(1, 2)
, не могут быть помечены из-за ожиданияNUM
; - Если я напишу
NUM
раньшеINT
, отдельные выражения, такие как(1)
, не могут быть помечены из-за ожидания aINT
.
grammar Expr;
prog : single | pair ;
single : '(' INT ')' ;
pair : '(' NUM ',' NUM ')' ;
INT : [0-9] ;
NUM : INT | FLOAT ;
FLOAT : '-'? INT '.' INT ;
WS : [ trn] -> skip ;
Чтобы оба выражения можно было маркировать, я могу удалить NUM
lexer и вручную написать pair
, как:
pair : '(' INT ',' INT ')'
| '(' INT ',' FLOAT ')'
| '(' FLOAT ',' INT ')'
| '(' FLOAT ',' FLOAT ')'
;
тогда можно анализировать оба выражения, а выражение pair поддерживает как целые числа, так и числа с плавающей запятой.
Но это глупо, поскольку, если это не пара, а tuple10, невозможно записать 1024 случая.
Есть ли лучшее решение?
Комментарии:
1. ДА. Поднимите NUM до уровня синтаксического анализатора,
num : INT | FLOAT; tuple10 : '(' num, num, num, ....... ')';
, и удалите NUM .
Ответ №1:
Как уже упоминалось в комментарии kaby76: переход NUM
к правилу синтаксического анализа. Не имеет большого смысла определять INT
и FLOAT
в лексере, а затем определять a NUM
, который создает токены INT
и FLOAT
никогда не становится реальными токенами самостоятельно.
prog : single | pair ;
single : '(' INT ')' ;
pair : '(' num ',' num ')' ;
num : INT | FLOAT ;
INT : [0-9] ;
FLOAT : '-'? INT '.' INT ;
WS : [ trn] -> skip ;