在编程语言中标记省略号以避免浮点

问题描述 投票:0回答:3

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

如何让 flex 支持这种语法?是不是就像让 0. 成为无效浮点数那么简单?

floating-point lex tokenize ellipsis
3个回答
3
投票

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; }

这些模式可以单独具有或不具有尾随上下文。

附注如果我改变主意并不允许

123.
,我就会删除
FLODOT
的所有痕迹。

错误:

此代码必须反转:

<SPECIAL,NESTED,BRACED>{FLODOT}/[^.] |
<SPECIAL,NESTED,BRACED>{FLO}         {

<SPECIAL,NESTED,BRACED>{FLO}         |
<SPECIAL,NESTED,BRACED>{FLODOT}/[^.] {

看起来

flex
正在考虑匹配的尾随上下文到匹配长度的一部分。即,在
3.0
情况下,
FLODOT
被视为三字符匹配,即使提取的标记是
3.
。所以我们必须把这种情况放在第二位,以便通过
3.0
匹配出现
FLO


1
投票

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


0
投票

使用卡兹的答案,我解决了省略号词法分析,如下所示。 我必须将一条规则分成两条才能使其发挥作用。

/* numbers like 5.1 and .5 */

[0-9]+.[0-9]+|.[0-9]+ { }

/* numbers like 5. but not 5.. */
/* The trailing context helps us tokenize 1..10 as INT, DOTDOT, INT */
/* instead of FLOAT, DOT, INT */

[0-9]+./[^.] { }

© www.soinside.com 2019 - 2024. All rights reserved.