Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在Flex(词法分析器)中定义数字格式?_C_Compiler Construction_Flex Lexer_Lex_Lexical Analysis - Fatal编程技术网

C 如何在Flex(词法分析器)中定义数字格式?

C 如何在Flex(词法分析器)中定义数字格式?,c,compiler-construction,flex-lexer,lex,lexical-analysis,C,Compiler Construction,Flex Lexer,Lex,Lexical Analysis,我需要的是: 可接受>1234和12.34 错误不可接受>12.34.56 L: ... %% [0-9]+ printf("Number "); [0-9]+"."[0-9]+ printf("Decimal_Number "); "." printf("Dot "): %% ... 编译和运行后: Input : 1234 12.34 12.34.65 Output :

我需要的是:

可接受>1234和12.34

错误不可接受>12.34.56

L:

      ...
%%

[0-9]+                printf("Number ");
[0-9]+"."[0-9]+       printf("Decimal_Number ");
"."                   printf("Dot "):

%%
      ...
编译和运行后:

Input :
1234    12.34    12.34.65

Output :
Number    Decimal_Number      Decimal_Number Dot Number
如何打印错误而不是小数点或忽略它


是否可以将数字前后的空格定义为分隔符

这不是词法分析器的职责,而是解析器yacc或bison的职责。如果你定义。作为一个有效的符号,我们毫不奇怪

12.34.56
标记为

Decimal_Number Dot Number

关键是解析器不会有一个接受该令牌序列的规则,因此稍后会引发错误。空白通常被忽略,因此在数字之间强制使用空格是没有意义的,特别是在您可能有12.34+56.78而不会标记为十进制数二进制运算符十进制数的上下文中,因为它缺少空格。

通常认为在解析器中检测12.34.56之类的错误比在扫描仪中检测更好。但也有一种观点认为,通过对错误进行词汇检测,可以产生更好的错误消息

如果你想这样做,你可以使用两种模式;第一种方法只检测正确的数字,第二种方法检测更大的字符串集,包括所有错误的字符串,但不检测任何合法的字符串。这取决于flex的匹配行为:它总是接受最长的匹配,如果最长的令牌由两个或多个规则匹配,它将使用第一个匹配规则

例如,假设您希望将点本身接受为“.”,将数字接受为数字标记,并在包含多个点的数字字符串上生成错误。你可以通过三条规则做到这一点:

  /* If the token is just a dot, match it here */
\.                             { return '.';    }
  /* Match integers without decimal points */
[[:digit:]]+                   { return INTEGER; }
  /* If the token is a number including a decimal point,
   * match it here. This pattern will also match just '.',
   * but the previous rules will be preferred.) */
[[:digit:]]*\.[[:digit:]]*     { return FLOAT; }
  /* This rule matches any sequence of dots and digits.
   * That will also match single dots and correct numbers, but
   * again, the previous rules are preferred. */
[.[:digit:]]+                  { /* signal error */
                                 return BADNUMBER; }
您需要非常小心使用上述解决方案。例如,最后一条规则将匹配。。和…,这可能是有效的标记,甚至是有效的序列。代币

例如,假设您的语言允许范围表达式,如4。。17表示从4到17的整数列表,或类似的列表。您的用户可能希望4..17被接受为范围表达式,但即使在添加规则时,上述内容也会产生BADNUMBER错误

".."                           { return RANGE; }
一开始,因为。。将在扫描的上一点匹配BADNUMBER

为了避免错误警报,我们需要修改BADNUMBER规则,以避免匹配包含两个或多个连续点的字符串。我们还需要确保4..17没有被lexed为4。然后是0.17。第二个问题可以通过坚持这样做来避免。开始和结束都不是数字标记,但这可能会激怒一些用户

因此,我们从实际的点标记开始:

"."                            { return '.'; }
".."                           { return RANGE; }
"..."                          { return ELLIPSIS; }
为了避免过度匹配后跟..的数字,我们可以使用flex的尾部上下文操作符。在这里,我们识别一个以a结尾的数字序列。仅当字符串后跟除a以外的其他内容时才作为数字:

现在我们需要修正错误规则。首先,我们将其限制为识别每个点后面跟一个数字的字符串。然后,与上面类似,我们匹配的情况是,有一个尾随的点后面没有另一个点:

[[:digit:]]*(\.[[:digit:]]+)+  { return BADNUMBER; }
[[:digit:]]*(\.[[:digit:]]+)+\./[^.] { return BADNUMBER; }

你可以检查我的程序来处理你的问题。但是,当你尝试使用莱克斯时,你应该知道,只要它与任何情况匹配,它就会起作用。 现在更改如下:

%%

[0-9]+                {printf("Number ");}
[0-9]+[.][0-9]*[.]+[0-9|.]*       {printf("error ");}
[0-9]+[.][0-9]+       {printf("Decimal_Number ");}
%%
现在,程序可以按照您的需要工作

Input :
1234    12.34    12.34.65

Output :
Number    Decimal_Number     Error

你真的需要吗?12.34.56可能是一个语法错误,所以它不是一个词法错误真的很重要吗?所以没有一种方法可以实现我在Flex中所说的?也许可以搬走。定义还是什么?你的问题是一个XY问题,如果你真的想要,你可以在令牌中强制使用空格,就像你想要的一样,例如[0-9]+[0-9]+,但这是错误的,不应该被考虑。不,忽略空格的事情。有没有办法在Flex中返回错误或忽略12.34.56格式?谢谢,这很有帮助。感谢您的详细解释。在[0-9 |]中,|只是另一个字符,因此它将匹配文字|。@Md Shibbir Hossen-正是我想要的,非常感谢我添加的内容。{printfDot;},没有任何问题。不,这是或这里可能是0-9或。不是character |它在character类中,所以不,它不是或。这只是另一个角色。如果你想写一个数字或,你可以写[0-9.]。
Input :
1234    12.34    12.34.65

Output :
Number    Decimal_Number     Error