9 марта 2012 г.:
Если вы не хотите делать 0. недопустимым с плавающей точкой, вы можете использовать конечный контекст Lex:
[0-9]+[.]/[^.] { /* recognize <digits>. only if not followed by another . */ }
Так что это правило будетотклонено из-за несоответствия конечного контекста, и токен совпадает только как целочисленная константа.Тогда следующий ввод - ..
, который может быть распознан как токен-точка-точка.
20 марта 2012 г .:
Мне нужно будет сейчас воспользоваться моим собственным советом!
Регрессия от добавления поддержки с плавающей запятой:
$ ./txr -v -l -c '@(bind a (1..3))'
spec:
(((bind a (1.0 0.3)))) # oops, should be (cons 1 3)
bindings:
nil
(a 1.0 0.3)
:) Та же проблема.Токен DOTDOT на языке, и плавающие, которые могут начинаться с точки и заканчиваться точкой.
Мое предлагаемое решение не будет таким простым для применения, потому что токен с плавающей запятой сопоставляется с одним сложным регулярным выражением, где совпадение для десятичной точки находится где-то посередине, перед некоторыми необязательными цифрами ираздел экспоненты.Конечный контекст lex
может быть только в конце.
Необходимо изменить выражение, чтобы оно не распознавало 123.
как действительный токен, и распознавать 123.
с дополнительным правилом.который имеет конечный контекст.
Рабочее исправление из фактического кода:
diff --git a/parser.l b/parser.l
index d8fd915..449cc14 100644
--- a/parser.l
+++ b/parser.l
@@ -149,8 +149,12 @@ static wchar_t num_esc(char *num)
%option noinput
SYM [a-zA-Z0-9_]+
-NUM [+\-]?[0-9]+
-FLO [+\-]?([0-9]+[.]?[0-9]*|[0-9]*[.][0-9]+)([eE][+-]?[0-9]+)?
+SGN [+\-]
+EXP [eE][+\-]?[0-9]+
+DIG [0-9]
+NUM {SGN}?{DIG}+
+FLO {SGN}?{DIG}*[.]({DIG}+{EXP}?|{EXP})
+FLODOT {SGN}?{DIG}+[.]
BSCHR [a-zA-Z0-9!$%&*+\-<=>?\\^_~]
BSYM {BSCHR}({BSCHR}|#)*
NSCHR [a-zA-Z0-9!$%&*+\-<=>?\\^_~/]
@@ -190,7 +194,8 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
return NUMBER;
}
-<SPECIAL,NESTED,BRACED>{FLO} {
+<SPECIAL,NESTED,BRACED>{FLODOT}/[^.] |
+<SPECIAL,NESTED,BRACED>{FLO} {
val str = string_own(utf8_dup_from(yytext));
if (yy_top_state() == INITIAL
Таким образом, плавающие константы теперь имеют две формы:
необязательный знак, за которым следуют ноль или более цифр и десятичная точка, за которой следует либо показатель степени, либо цифры и, возможно, показатель степени.
цифр, за которыми следует точка, с последующим контекстом, утверждающим, что следующаяchar - это не точка.
Обратите внимание, что вышеприведенный пример демонстрирует технику нескольких паттернов (с их собственными flex
начальными состояниями), которые используют одно и то же правило:
PATTERN1 |
PATTERN2 |
...
PATTERNN { action; }
Шаблоны могут индивидуально иметь конечный контекст или нет.
PS Если я передумал и запретил 123.
, я просто удалил все следы FLODOT
.
Ошибка:
Этот код хаs для обращения:
<SPECIAL,NESTED,BRACED>{FLODOT}/[^.] |
<SPECIAL,NESTED,BRACED>{FLO} {
Т.е.
<SPECIAL,NESTED,BRACED>{FLO} |
<SPECIAL,NESTED,BRACED>{FLODOT}/[^.] {
Похоже, flex
рассматривает сопоставленный конечный контекст для части длины совпадения.Т.е. 3.0
считается совпадением из трех символов в случае FLODOT
, хотя извлеченный токен равен 3.
.Таким образом, мы должны поставить этот случай на второе место, чтобы 3.0
вышло через FLO
match.