如何使用Perl解析C头文件?

技术标签: Python  C  Perl.  解析  标题文件

我有一个标题文件,其中有一个大结构。我需要使用某些程序读取此结构,并在结构的每个成员上进行一些操作并将其写回。

例如,我有一些结构

const BYTE Some_Idx[] = {
4,7,10,15,17,19,24,29,
31,32,35,45,49,51,52,54,
55,58,60,64,65,66,67,69,
70,72,76,77,81,82,83,85,
88,93,94,95,97,99,102,103,
105,106,113,115,122,124,125,126,
129,131,137,139,140,149,151,152,
153,155,158,159,160,163,165,169,
174,175,181,182,183,189,190,193,
197,201,204,206,208,210,211,212,
213,214,215,217,218,219,220,223,
225,228,230,234,236,237,240,241,
242,247,249};

现在,我需要读取这个并在每个成员变量上应用一些操作,并以不同的顺序创建新结构,类似:

const BYTE Some_Idx_Mod_mul_2[] = {
8,14,20, ...
...
484,494,498};

是否有任何Perl库已经可用?如果不是perl,那么像python这样的东西也可以。

有人可以帮忙!

看答案

保持您的数据在标题中展示的数据使其令人棘手使用Perl等其他程序。您可能考虑的另一种方法是将此数据保存在数据库或其他文件中,并根据需要重新生成您的头文件,可能是构建系统的一部分。原因是生成C比解析C要容易得多,写入解析文本文件的脚本并为您制作标题,并且甚至可以从构建系统调用这样的脚本。

假设您要在C头文件中保持数据,您需要两件事之一来解决此问题:

  • 快速的一次性脚本,以确切地解析(或靠近完全)您描述的输入。
  • 一般,写的脚本,可以解析任意C并一般上工作到大量的不同标题。

第一个案例似乎比对我更常见,但如果通过需要解析任意C或需要解析此特定文件的脚本的脚本更好,这很难从您的问题中解释。对于在特定情况下工作的代码,以下对我的输入工作:

#!/usr/bin/perl -w

use strict;

open FILE, "<header.h" or die $!;
my @file = <FILE>;
close FILE or die $!;

my $in_block = 0;
my $regex = 'Some_Idx\[\]';
my $byte_line = '';
my @byte_entries;
foreach my $line (@file) {
    chomp $line;

    if ( $line =~ /$regex.*\{(.*)/ ) {
        $in_block = 1;
        my @digits = @{ match_digits($1) };
        push @digits, @byte_entries;
        next;
    }

    if ( $in_block ) {
        my @digits = @{ match_digits($line) };
        push @byte_entries, @digits;
    }

    if ( $line =~ /\}/ ) {
        $in_block = 0;
    }
}

print "const BYTE Some_Idx_Mod_mul_2[] = {\n";
print join ",", map { $_ * 2 } @byte_entries;
print "};\n";

sub match_digits {
    my $text = shift;
    my @digits;
    while ( $text =~ /(\d+),*/g ) {
        push @digits, $1;
    }

    return \@digits;
}

解析任意C是有点棘手,对许多应用程序不值得,但也许您需要实际执行此操作。一个诀窍是让GCC为您进行解析,并使用命名的CPAN模块在GCC的解析树中读取 GCC :: TranslationUnit.。以下是编译代码的gcc命令,假设您有一个名为test.c:

GCC -Fdump-Plannell-Unit -C Test.C

这是Parse树中读取的Perl代码:

  use GCC::TranslationUnit;

  # echo '#include <stdio.h>' > stdio.c
  # gcc -fdump-translation-unit -c stdio.c
  $node = GCC::TranslationUnit::Parser->parsefile('stdio.c.tu')->root;

  # list every function/variable name
  while($node) {
    if($node->isa('GCC::Node::function_decl') or
       $node->isa('GCC::Node::var_decl')) {
      printf "%s declared in %s\n",
        $node->name->identifier, $node->source;
    }
  } continue {
    $node = $node->chain;
  }

智能推荐

C++头文件cstddef

头文件cstddef与其C对应版本兼容,它是C头文件<stddef.h>较新版本,定义了常用的常量、宏、类型和函数 <cstddef>内的各项定义 NULL : 指针值用来表示未定义或无值 nullptr_t : nullptr的类型 size_t :一种无正负号类型,用来表示大小(比如元素的个数) ptrdiff_t :一种带正负号类型,用来表示指针之间的距离 max_a...

[C&C++]头文件包含问题

原创文章,欢迎转载。转载请注明:转载自 祥的博客 原文链接:https://blog.csdn.net/humanking7/article/details/79299045 先占个坑-后补 以前自己搭建起来的一个稍微大一点的项目,就会发现一些当初架构起来的问题,头文件包含乱用,导致后期分外蛋疼,我遇到大致两种问题: 头文件全部包含,使得预编译会剔除某个头文件,导致结果:编译单个源文件没有问题,整...

c/c++头文件的作用

在编程过程中,程序代码往往被拆成很多部分,每部分放在一个独立的源文 件中,而不是将所有的代码放在一个源文件中。考虑一个简单的小例子:程序中 有两个函数main()和foo()。main()函数位于main.cpp,foo()函数位于foo.cpp, main()函数中调用foo()函数。在编译阶段,由于编译是对单个文件进行编译,所 以编译main.cpp 时,编译器不知道是否存在foo()函数以及...

C/C++头文件的引用

C/C++头文件的引用问题(#include使用)     Main.c 中需要引用头文件 func1.h:处于同一文件夹下   Main.c 中需要引用头文件func2.h:fun2.h处于main的平行子文件夹下   Mian.c 中需要引用头文件func3.h:func3.h处于main的上级文件夹下  ...

图片头文件信息解析

2019独角兽企业重金招聘Python工程师标准>>> 获取图片的宽高,并不需要把图片完全读完之后再来获取,而只需要读取文件头文件,几十个字节便可以读出文件的宽高。   图片的文件头部存储有该图片相关信息,可以从中读取相应字段,得到尺寸、大小、格式等信息。由于无需载入整张图片,故而速度较快。当图片较大时,优势更加明显。   现在把今天发现的东西总结一下,所有数据都是用的QQ截图。...

猜你喜欢

C语言 文件操作的头文件

C语言 文件操作的头文件         计算机文件是以计算机硬盘为载体存储在计算机上的信息集合,是存储在某种长期储存设备上的一段数据流。在C语言中用一个指针变量指向一个文件,这个指针称为文件指针。通过文件指针就可对它所指的文件进行各种操作,C语言规定该文件指针类型为FILE型。文件的信息有这个FILE型的结构体来进行定义。 FILE的结构体的定义如下 例如...

Dev C++ C语言中使用头文件的问题

Dev C++ 用C语言中使用头文件#inlcude<math.h>的问题 报错:[Error] stray ‘#’ in program,如下图: 原因不知 解决方法: 点击工具->编译器选项->代码生成/优化->C编译器:->试图支持 traditionalC 预编译特性,选择No。...

无意中发现看书也是一种美

2012年4月25日晚,翻翻自己喜欢的一门语言学习书(python参考手册),无意中发现书中夹着之前的明信片(有一次和同事一起去前门邓丽君音乐生活馆留下来的),感觉学习也是一种美!于是乎拍下这不经意的时刻,哈哈!...

香橙派OrangePi PC Plus开发板连接USB以太网卡测试说明

1) 目前测试过能用的 USB 以太网卡如下所示,其中 RTL8153 USB 千兆网卡插入开 发板的 USB 2.0 Host 接口中测试可以正常使用,但是速率是达不到千兆的,这点请 注意   2) 首先将 USB 网卡插入开发板的 USB 接口中,然后在 USB 网卡中插入网线,确 保网线能正常上网,如果通过 dmesg 命令可以看到下面的 log 信息,说明 USB 网卡...

计算机网络基础:Vlan,网关,dns吗,子网掩码等!面试必备!

很多朋友多次问到什么是网关、dns、子网掩码,三层交换机,它们定位的用途;确实,因为网络技术在弱电中确实应用非常广泛,我们平时在 vip 技术群中也是不断的讨论到网关、vlan、三层交换机或子网掩码等问题,今天我们就一起用通俗方式一次性了解清楚。 一、什么是 vlan? VLAN 中文是 “虚拟局域网”。LAN 可以是由少数几台家用计算机构成的网络,也可以是数以百计的计算机...

问答精选

How to extract beta coefficients for interaction effect in R?

I am examining the interaction between a continuous variable (bloodq) and a categorical variable with three levels (ER, RB, and WB). In order to see how the betas differ across tissue types, I would l...

what is the difference between Flatten() and GlobalAveragePooling2D() in keras

I want to pass the output of ConvLSTM and Conv2D to a Dense Layer in Keras, what is the difference between using global average pooling and flatten Both is working in my case. That both seem to work d...

How to invoke a test step with inputs at runtime from groovy script in SOAP UI?

I am writing a validation groovy script for a test step, intended to test a SOAP Web Service. Now, I want to call the same test step, with different input value from the groovy script. Is it possible?...

Wicket pagestore results wrong page

I have a problem with my web application with wicket. I am using wicket 6.14. I can't say exactly what the problem is, but I can describe the problem. I am using a self written pagestore, which uses h...

Unity load files from outside of resources folder

In unity is it possible to load a resource that is out side of the resources folder. I want the user to be able to set a textAsset variable from a file outside of the Assets directory entirely. You ca...

相关问题

相关文章

热门文章

推荐文章

相关标签

推荐问答