Parsing Lex解析以确定
这是对上一个问题的延伸。我试图解析一个.txt文件,并根据我的规则确定每一行是否有效。文本文件将包含由单个空格分隔的随机字符串、十六进制、整数和小数,例如:Parsing Lex解析以确定,parsing,flex-lexer,lex,Parsing,Flex Lexer,Lex,这是对上一个问题的延伸。我试图解析一个.txt文件,并根据我的规则确定每一行是否有效。文本文件将包含由单个空格分隔的随机字符串、十六进制、整数和小数,例如: 5 -0xA98F 0XA98H text hello 2.3 -12 0xabc 我试图识别有效的十六进制、整数和小数,并得到这样的输出 5 valid -0xA98F valid 0xA98H invalid text invalid hello invalid 2.3 valid -12 valid 0xabc invalid 但
5 -0xA98F 0XA98H text hello 2.3 -12 0xabc
我试图识别有效的十六进制、整数和小数,并得到这样的输出
5 valid
-0xA98F valid
0xA98H invalid
text invalid
hello invalid
2.3 valid
-12 valid
0xabc invalid
但是,我的当前代码显示如下:
5 valid
-0xa98f valid
0xA98 valid <--- issue 1 just remoives the H
2.3 valid <--- ignores text and hello
-12 valid
0xabc invalid
5有效
-0xa98f有效
0xA98 valid使用flex解决此类问题的关键是理解“”规则。规则很简单:Flex总是选择与匹配最长字符串的模式对应的操作(从当前输入点开始;Flex从不“搜索”匹配项)。如果有多个模式匹配相同的最长子字符串,则选择Flex描述中的第一个模式。这意味着规则的顺序很重要
有关这一点的详细说明,请参阅Flex手册中的
假设您对匹配完整单词感兴趣,其中“单词”是由任意非空白字符组成的非空序列,由空白分隔。(例如,行3、4和5.
将只包含一个有效字符串。)
很容易确定四种可能性:
十进制整数
十进制浮点
十六进制整数
还有别的词吗
我们还需要忽略空白,而不是将其识别为单词分隔符
如果我们将规则按此顺序排列,我们可以确信将为每一行选择正确的规则,因为最大芒克规则
下面是整个flex文件(除了main
的定义):
笔记
我在这里使用了普通的printf
语句。当然,你可以自由使用C++流,但是我更喜欢使用<代码> STDIO。包含#include
可能会被认为更干净,但事实上Flex已经这样做了,因为它自己需要它
%选项
语句告诉flex您不需要yywrap
(这意味着您不需要提供一个或链接到-lfl
),您不需要使用输入
或取消输出
(这意味着您可以使用-Wall
进行编译,而不会得到未使用的函数警告)而且您不希望flex需要插入默认规则(这可以避免令人尴尬的错误,因为flex会在有任何可能与任何规则不匹配的情况下警告您)
我在十六进制模式中使用了[:xdigit:][]+
,它允许使用大写和小写十六进制数字。如果不需要这样做,您可以将其替换为原始代码中的[0-9A-F]
,但您的示例似乎表明原始代码不正确。当然,您可以写出posix字符类,但我发现它们更可读。有关完整列表,请参阅上的Flex手册部分
使用flex解决此类问题的关键是理解“”规则。规则很简单:Flex总是选择与匹配最长字符串的模式对应的操作(从当前输入点开始;Flex从不“搜索”匹配项)。如果有多个模式匹配相同的最长子字符串,则选择Flex描述中的第一个模式。这意味着规则的顺序很重要
有关这一点的详细说明,请参阅Flex手册中的
假设您对匹配完整单词感兴趣,其中“单词”是由任意非空白字符组成的非空序列,由空白分隔。(例如,行3、4和5.
将只包含一个有效字符串。)
很容易确定四种可能性:
十进制整数
十进制浮点
十六进制整数
还有别的词吗
我们还需要忽略空白,而不是将其识别为单词分隔符
如果我们将规则按此顺序排列,我们可以确信将为每一行选择正确的规则,因为最大芒克规则
下面是整个flex文件(除了main
的定义):
笔记
我在这里使用了普通的printf
语句。当然,你可以自由使用C++流,但是我更喜欢使用<代码> STDIO。包含#include
可能会被认为更干净,但事实上Flex已经这样做了,因为它自己需要它
%选项
语句告诉flex您不需要yywrap
(这意味着您不需要提供一个或链接到-lfl
),您不需要使用输入
或取消输出
(这意味着您可以使用-Wall
进行编译,而不会得到未使用的函数警告)而且您不希望flex需要插入默认规则(这可以避免令人尴尬的错误,因为flex会在有任何可能与任何规则不匹配的情况下警告您)
我在十六进制模式中使用了[:xdigit:][]+
,它允许使用大写和小写十六进制数字。如果不需要这样做,您可以将其替换为原始代码中的[0-9A-F]
,但您的示例似乎表明原始代码不正确。当然,您可以写出posix字符类,但我发现它们更可读。有关完整列表,请参阅上的Flex手册部分
你的文件中的“东西”是像你的问题一样每行一个,还是像你的例子中那样用不同的空格分隔的单词?它们通常像我的例子一样用空格分隔。输出是每行唯一一个。请编辑您的问题以使要求更精确。评论不算数。“东西”到底是什么?有限公司
%{
#include <iostream>
using namespace std;
%}
Decimal [+-]?[0-9]+\.[0-9]+?
Integers [+-]?[0-9]+
Hex [-]?[0][xX][0-9A-F]+
%%
[ \t\n] ;
{Decimal} {cout << yytext << "Valid" << endl; }
{Integers} { cout << yytext << "Valid" << endl; }
{Hex} {cout << yytext << " Valid" << endl;}
. ;
%%
main() {
FILE *myfile= fopen("something.txt", "r");
if (!myfile) {
cout << "Error" << endl;
return -1;
}
yyin = myfile;
yylex();
fclose(yyin);
}
%option noinput nounput noyywrap nodefault
%%
[[:space:]]+ { /* Ignore whitespace */ }
[+-]?[[:digit:]]+ { printf("%s valid\n", yytext); /* Decimal integer */ }
[+-]?[[:digit:]]+"."[[:digit:]]* {
printf("%s valid\n", yytext); /* Decimal point */ }
[+-]?"."[[:digit:]]+ { printf("%s valid\n", yytext); /* Decimal point */ }
[+-]0[xX][[:xdigit:]]+ { printf("%s valid\n", yytext); /* Hexadecimal integer */ }
[^[:space:]]+ { printf("%s invalid\n", yytext); /* Any word not matched by above rules */ }