我正在设计一种我想使用 .. 来定义整数范围的语言。问题是 0..10 被标记为浮点数 0. 和 .10。
如何允许使用 flex 支持这种语法?将 0. 设为无效浮点数很简单吗?
我正在设计一种我想使用 .. 来定义整数范围的语言。问题是 0..10 被标记为浮点数 0. 和 .10。
如何允许使用 flex 支持这种语法?将 0. 设为无效浮点数很简单吗?
如果您不想使 0. 成为无效浮点数,则可以使用 Lex 尾随上下文:
[0-9]+[.]/[^.] { /* recognize <digits>. only if not followed by another . */ }
所以这条规则将根据尾随上下文不匹配而被拒绝,并且令牌仅作为整数常量匹配。然后下一个输入是..
可以被识别为点点标记的。
我现在必须接受我自己的建议!
添加浮点支持的回归:
$ ./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
所以浮动常量现在有两种形式:
可选符号,后跟零个或多个数字,以及一个小数点,后跟一个指数,或数字和可选的指数。
数字后跟点,尾随上下文断言下一个字符不是点。
flex
请注意上面如何演示共享相同规则的多个模式(也具有自己的起始状态)的技术:
PATTERN1 |
PATTERN2 |
...
PATTERNN { action; }
这些模式可以单独有尾随上下文,也可以没有。
PS如果我改变主意并不允许123.
,我只是删除所有痕迹FLODOT
。
此代码必须颠倒:
<SPECIAL,NESTED,BRACED>{FLODOT}/[^.] |
<SPECIAL,NESTED,BRACED>{FLO} {
IE
<SPECIAL,NESTED,BRACED>{FLO} |
<SPECIAL,NESTED,BRACED>{FLODOT}/[^.] {
看起来flex
正在考虑将匹配的尾随上下文作为匹配长度的一部分。即使提取的标记是 .ie 在这种情况下也被3.0
认为是三字符匹配。所以我们必须把这个案例放在第二位,这样才能通过比赛出来。FLODOT
3.
3.0
FLO
这实际上取决于您如何定义词法分析器。如果您将省略号定义为由两个句点组成的标记,并且还正确定义了浮点数,则不应存在冲突。只需确保在您的规范中首先定义省略号的标记。而且,是的,0. 应该是一个无效的浮点数。