Parsing Lex解析以确定

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 但

这是对上一个问题的延伸。我试图解析一个.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 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 */ }