【问题标题】:Determining a hex value from a lex parser从 lex 解析器确定十六进制值
【发布时间】:2017-03-04 07:34:24
【问题描述】:

我目前正在尝试解析一个文本文件并在其中查找任何十六进制数字。如果十六进制数不正确,我会将其显示为非数字。

input:   

-0xA98F 
0XA98H
0x123 
0xabc

expected output:
-0xA98F valid
 0x123  valid
 0xabc  not valid
 0xA98H not valid

我的问题是,如果我得到类似 0xA98H 的内容,它将输出为 0xA98 并显示为数字。我的目标是让我的输出像我的示例一样,但是我没有看到任何解决我的问题的方法。

  [-]?[0][x|X][0-9A-F]+ {cout << yytext << " Number" << endl; }

【问题讨论】:

  • 简而言之,我希望忽略此值而不是显示 0xA98,而是显示为 0xA98H = 不是数字
  • 您为什么要创建一个新问题而不是编辑您的原始问题。当您改进问题时,我会改进我对您之前的问题lex parser not displaying hex correctly 的回答。
  • 第一个匹配第二个不匹配的模式很容易修改。但是,只要我不知道 1. 输入中还可能发生什么 2. 还必须匹配(或不匹配)什么,这种努力就毫无价值。请提供(不要太长)示例输入以及预期的输出。
  • 输入中唯一会出现的是各种假/正十六进制值。我为输入示例编辑了我的帖子。

标签: parsing flex-lexer lex


【解决方案1】:

以下示例代码根据 OP 的要求接受十六进制数:

%{
#include <iostream>
#include <string>
using namespace std;

static bool error = false;
static string buffer;
%}

HEX "-"?"0"[xX][0-9A-F]+
EOL (\n|\r|\r\n)

%%

{HEX} { buffer += yytext; }
" " { /* ignore spaces */ }
. { buffer += yytext; error = true; }
{EOL}+ {
  cout << buffer << '\t' << (error ? "not valid" : "valid") << endl;
  buffer.clear();
  error = false;
}

%%

int main(int argc, char **argv) { return yylex(); }

int yywrap() { return 1; }

使用 flex 和 g++ 编译并在 cygwin 上测试:

$ flex -otest-hex.cc test-hex.l ; g++ -o test-hex test-hex.cc

$ echo '-0xA98F                                              
> 0XA98H
> 0x123
> 0xabc
>' | ./test-hex
-0xA98F valid
0XA98H  not valid
0x123   valid
0xabc   not valid

$

空格和空行被忽略。

(\n|\r|\r\n) 表示匹配类 Unix 行尾、类 MacOS 行尾和类 DOS/Windows 行尾(按此顺序)的模式。

【讨论】:

  • 我也很好奇这段代码是否会忽略其他数字,例如小数和整数。
  • @sippycup 它会/应该由于模式中的"0"[xX] 部分。以下规则适用于 flex 生成的扫描器: 模式必须完全匹配才能匹配文本。如果多个模式匹配,则最长的匹配获胜。如果多个模式匹配相同长度的文本,则第一个规则获胜。 (其余的您可以在 man flex、info flex 或 Flex Manual 中找到。
猜你喜欢
  • 1970-01-01
  • 2022-11-16
  • 2010-12-30
  • 2018-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
相关资源
最近更新 更多