如何跳过 Flex 中的空格?
How to skip blank spaces in Flex?
我正在使用 flex 为大学作业生成词法分析器。它应该识别整数、浮点数、变量名称和数学运算符。它还应忽略任何空白,如字符,如 " "、"\n"、"\t" 等。首先,我只尝试捕获像这样的空白字符 " " 或更多连接的空白字符。我的规则文件是这样的:
%{
#include<stdio.h>
%}
%%
[0-9]+ printf("inteiro:%s\n",yytext);
[0-9]+\.[0-9]+ printf("fracionário:%s\n",yytext);
[a-zA-Z][a-zA-z0-9]* printf("variável:%s\n",yytext);
\+|\-|\*|\/|\*\* printf("operador:%s\n",yytext);
\(|\) printf("parênteses:%s\n",yytext);
[[:space:]]|[[:space:]]+;
%%
使用以下输入
12 + 413
它生成此输出:
inteiro:12
operador:+
inteiro:413
我想知道为什么最后一行不能是这样的:
[[:space:]]+;
规则
[[:space:]]|[[:space:]]+;
有点奇怪。
弹性规则由模式和(可选)操作组成,由白色space分隔。由于 ;
之前没有 space,它是模式的一部分,而不是动作。因此该模式匹配单个白色space字符([[:space:]]
)或(|
)一个或多个白色space字符后跟分号([[:space:]]+;
).
由于该规则中没有任何操作,因此该模式将被忽略。 (这是一个 flex 扩展。Lex 要求存在一个动作,即使它什么都不做。)实际上,这意味着您将忽略所有白色 space(一次一个字符)并且您还将忽略分号如果它们前面有 whitespace.
您可能想要的是
[[:space:]]+ /* sem ação */
(插入注释以使缺少的操作可见是很有用的。)
顺便说一下,字符 classes 通常比一堆倾斜的木材(即一堆反斜杠转义符)更具可读性。此外,flex 允许您使用双引号来引用字符串。
所以不用
\+|\-|\*|\/|\*\* /* operador */
\(|\) /* parênteses */
你可以写:
[-+*/]|"**" /* operador */
[()] /* parênteses */
在第一个字符 class 中,将 - 放在字符列表的开头或结尾很重要,这样它就不会被解释定义字符范围。
并且,不要插入您自己的调试 printf 语句,而是在构建扫描仪时考虑使用 -d
(调试)选项。这将为您打印出完整的调试信息,让您准确地看到扫描仪正在做什么。
我正在使用 flex 为大学作业生成词法分析器。它应该识别整数、浮点数、变量名称和数学运算符。它还应忽略任何空白,如字符,如 " "、"\n"、"\t" 等。首先,我只尝试捕获像这样的空白字符 " " 或更多连接的空白字符。我的规则文件是这样的:
%{
#include<stdio.h>
%}
%%
[0-9]+ printf("inteiro:%s\n",yytext);
[0-9]+\.[0-9]+ printf("fracionário:%s\n",yytext);
[a-zA-Z][a-zA-z0-9]* printf("variável:%s\n",yytext);
\+|\-|\*|\/|\*\* printf("operador:%s\n",yytext);
\(|\) printf("parênteses:%s\n",yytext);
[[:space:]]|[[:space:]]+;
%%
使用以下输入
12 + 413
它生成此输出:
inteiro:12
operador:+
inteiro:413
我想知道为什么最后一行不能是这样的:
[[:space:]]+;
规则
[[:space:]]|[[:space:]]+;
有点奇怪。
弹性规则由模式和(可选)操作组成,由白色space分隔。由于 ;
之前没有 space,它是模式的一部分,而不是动作。因此该模式匹配单个白色space字符([[:space:]]
)或(|
)一个或多个白色space字符后跟分号([[:space:]]+;
).
由于该规则中没有任何操作,因此该模式将被忽略。 (这是一个 flex 扩展。Lex 要求存在一个动作,即使它什么都不做。)实际上,这意味着您将忽略所有白色 space(一次一个字符)并且您还将忽略分号如果它们前面有 whitespace.
您可能想要的是
[[:space:]]+ /* sem ação */
(插入注释以使缺少的操作可见是很有用的。)
顺便说一下,字符 classes 通常比一堆倾斜的木材(即一堆反斜杠转义符)更具可读性。此外,flex 允许您使用双引号来引用字符串。
所以不用
\+|\-|\*|\/|\*\* /* operador */
\(|\) /* parênteses */
你可以写:
[-+*/]|"**" /* operador */
[()] /* parênteses */
在第一个字符 class 中,将 - 放在字符列表的开头或结尾很重要,这样它就不会被解释定义字符范围。
并且,不要插入您自己的调试 printf 语句,而是在构建扫描仪时考虑使用 -d
(调试)选项。这将为您打印出完整的调试信息,让您准确地看到扫描仪正在做什么。