0

我正在设计一种我想使用 .. 来定义整数范围的语言。问题是 0..10 被标记为浮点数 0. 和 .10。

如何允许使用 flex 支持这种语法?将 0. 设为无效浮点数很简单吗?

4

2 回答 2

2

2012 年 3 月 9 日:

如果您不想使 0. 成为无效浮点数,则可以使用 Lex 尾随上下文:

[0-9]+[.]/[^.]  { /* recognize <digits>. only if not followed by another . */ }

所以这条规则将根据尾随上下文不匹配而被拒绝,并且令牌仅作为整数常量匹配。然后下一个输入是..可以被识别为点点标记的。

2012 年 3 月 20 日:

我现在必须接受我自己的建议!

添加浮点支持的回归:

$ ./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

所以浮动常量现在有两种形式:

  1. 可选符号,后跟零个或多个数字,以及一个小数点,后跟一个指数,或数字和可选的指数。

  2. 数字后跟点,尾随上下文断言下一个字符不是点。

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认为是三字符匹配。所以我们必须把这个案例放在第二位,这样才能通过比赛出来。FLODOT3.3.0FLO

于 2012-03-09T01:38:52.683 回答
1

这实际上取决于您如何定义词法分析器。如果您将省略号定义为由两个句点组成的标记,并且还正确定义了浮点数,则不应存在冲突。只需确保在您的规范中首先定义省略号的标记。而且,是的,0. 应该是一个无效的浮点数。

于 2012-02-28T14:32:32.540 回答