Обратите внимание, что ваше правило ANTLR:
EMPTY : '""';
не соответствует пустой строке, но содержит две двойные кавычки.
Но вы не хотите, чтобы правило лексера совпадало с только пустая строка: это приведет к бесконечному циклу, поскольку в любой строке / источнике есть бесконечное количество пустых строк.
Итак, правила BNF:
<real 10>
::= <sign> <ureal 10>
<sign>
::= <empty> | {+} | {-}
следует не переводить как следующие правила ANTLR:
REAL_10
: SIGN UREAL_10
;
SIGN
: EMPTY
| '+'
| '-'
;
, но вместо этого:
REAL_10
: SIGN? UREAL_10
;
SIGN
: '+'
| '-'
;
Также обратите внимание, что ваше правило:
fragment COMPLEX_10
: REAL_10 (
'@' REAL_10
| '+' (
UREAL_10 'i'
| 'i'
)?
| '-' (
UREAL_10 'i'
| 'i'
)?
)?
| '+' (
UREAL_10 'i'
| 'i'
)?
| '-' (
UREAL_10 'i'
| 'i'
)?;
немного трудно читать.Отступы по-другому могут сделать это немного более понятным:
fragment COMPLEX_10
: REAL_10 ( '@' REAL_10
| '+' (UREAL_10 'i' | 'i')?
| '-' (UREAL_10 'i' | 'i')?
)?
| '+' (UREAL_10 'i' | 'i')?
| '-' (UREAL_10 'i' | 'i')?
;
, что можно упростить, написав:
fragment COMPLEX_10
: REAL_10 ('@' REAL_10)?
| REAL_10? ('+' | '-') UREAL_10? 'i'
;
Также имейте в виду, что во многих нотациях BNF нет различия между нижнимии прописные литералы.Поэтому вместо написания 'i'
в вашей грамматике ANTLR вы можете использовать ('i' | 'I')
.
EDIT
Себастьян написал:
но у меня все еще есть проблемы с правилом PREFIX_10
: fragment PREFIX_10 : RADIX_10? EXACTNESS? | EXACTNESS? RADIX_10?;
, которое говорит мне, что альтернатива 2 никогда не может быть сопоставлена, хотя она должна соответствовать #i #d
и #d #i
с2 варианта по отдельности или я что-то здесь не так делаю?
Есть пара вещей, которые не так с правилом (фрагмента) PREFIX_10
:
fragment PREFIX_10
: RADIX_10? EXACTNESS? // alternative 1
| EXACTNESS? RADIX_10? // alternative 2
;
Для одного, обоихсоответствует пустой строке.Поскольку альтернатива 1 будет всегда соответствовать пустой строке, альтернатива 2 никогда не будет совпадать, о чем ANTLR говорил вам.
Теперь рассмотрим правила BNF:
<exactness>
::= <empty> | {#i} | {#e}
<prefix 10>
::= <radix 10> <exactness>
| <exactness> <radix 10>
<radix 10>
::= <empty> {#d}
(Обратите внимание, что <empty> {#d}
равно {#d}
, поэтому <empty>
- это только IMO, неуместно. Все остальные радиусы не имеют и <empty>
part)
Iпереведите их в следующие ( непроверенные! ) правила ANTLR:
fragment EXACTNESS
: '#i'
| '#e'
;
fragment PREFIX_10
: RADIX_10 EXACTNESS?
| EXACTNESS RADIX_10 // **
;
fragment RADIX_10
: '#d'
;
** Обратите внимание, что не :
fragment PREFIX_10
: RADIX_10 EXACTNESS? // matches '#d'
| EXACTNESS? RADIX_10 // matches '#d'
;
, потому что лексер не знает, с какой альтернативой сопоставлять #d
.
И в случае, если правило BNF для <radix 10>
должно быть таким (т. Е. Они забыли разместить|
):
<radix 10>
::= <empty>
| {#d}
, тогда ANTLR PREFIX_10
должен выглядеть следующим образом:
fragment PREFIX_10
: RADIX_10 EXACTNESS?
| EXACTNESS RADIX_10
;
, но тогда все другие правила, использующие PREFIX_10
, должны сделать PREFIX_10
необязательным.
HTH