面试题:如何使用脚本语言获得一个CPP文件里声明的所有函数名?

matrix2009 2009-03-24 02:28:30
如题,如何使用脚本语言获得一个CPP文件里声明的所有函数名?
脚本语言我不会啊
不知道怎么写?
还有别的什么方法吗?
我当时是打开这个文件,逐个读取字符,在'}'和'{'之间是声明的函数名,
大家还有什么别的好办法吗?
对了,提示说还可以用正则表达式
但是我也不知道怎么写
大家帮帮忙
...全文
184 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
aaaa3105563 2009-03-24
  • 打赏
  • 举报
回复
呵呵 楼主自己都看晕咯
  • 打赏
  • 举报
回复
期待高人,原理只能是解析()符号吧
pengzhixi 2009-03-24
  • 打赏
  • 举报
回复
mark
matrix2009 2009-03-24
  • 打赏
  • 举报
回复
我晕
这也太复杂了吧
yyyapple 2009-03-24
  • 打赏
  • 举报
回复
续....
// DECLARE_INTERFACE_( IDirectDraw, IUnknown )
//
// STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE;
// STDMETHOD_(ULONG,AddRef) (THIS) PURE;

void KParser::CheckAPI(void)
{
NextToken();

// first token after a new line
if ( Equal("DECLARE_INTERFACE_") )
{
NextToken(); // (
NextToken(); // interface name

printf("\n[%s]\n", token);

return;
}

// <newline> WINGDIAPI
char line[MAX_PATH];

line[0] = 0;

int isapi = 0;

int identadmit = 100;

while ( ! Eof() && (isapi || token[0]!='\n') )
{
// rejecting pragmas
if ( Equal("#define") || Equal("#ifdef") || Equal("#ifndef") ||
Equal("#else") || Equal("#endif") || Equal("typedef")
)
return;

// API signals
if ( Equal("WINGDIAPI") || Equal("WINUSERAPI") ||
Equal("WINAPI") || Equal("APIENTRY") )
{
isapi = true;
NextToken();
continue;
}

// STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE;
if ( Equal("STDMETHOD") )
{
isapi = true;

NextToken(); // (
strcat(line, "HRESULT");
while ( strlen(line)<15 )
strcat(line, " ");

NextToken(); // name
strcat(line, token);
NextToken(); // )

NextToken(); // (
}

// STDMETHOD_(ULONG,AddRef) (THIS) PURE;
if ( Equal("STDMETHOD_") )
{
isapi = true;

NextToken(); // (
NextToken(); // type
strcat(line, token);
while ( strlen(line)<15 )
strcat(line, " ");

NextToken(); // ,
NextToken(); // name
strcat(line, token);
NextToken(); // )

NextToken(); // (
}

if ( Equal("THIS_") )
{
strcat(line, "THIS");
strcpy(token, ",");
}

// skipped words
if ( Equal("IN") || Equal("OUT") ||
Equal("CONST") || Equal("FAR") ||
Equal("extern") || Equal("PURE") ||
token[0]=='\n'
)
{
NextToken();
continue;
}

// ; is the end
if ( token[0] == ';' )
{
if ( isapi )
{
printf(line);
printf("\n");

CheckTypes(line);
}

NextToken();
return;
}

char copy[MAX_PATH];
strcpy(copy, token);

NextToken();

// before adding '(', add space to function name
if ( token[0]=='(' )
while ( strlen(line)<15 )
strcat(line, " ");

// skip parameter name
if ( copy[0]=='_' || isalpha(copy[0]) )
{
if ( identadmit )
{
identadmit --;
strcat(line, copy);
}
}
else
strcat(line, copy);

// after '(' or ',', one identifier only
if ( copy[0]=='(' || copy[0]==',' )
identadmit = 1;
}
}


int main( int argc, char *argv[ ], char *envp[ ] )
{
KParser parser;

if ( argc<2 )
{
printf("Skimmer: extracts function prototypes from Windows API header file\n");
printf("Usage: skimmer <headerfilename>\n");
return -1;
}

if ( !parser.Open(argv[1]) )
{
printf("Unable to open %s.\n", argv[1]);
return -1;
}

parser.token[0] = '\n';
parser.token[1] = 0;

printf("[%s]\n", argv[1]);

while ( ! parser.Eof() )
{
if ( parser.token[0] == '\n' ) // starting with a newline, check API
parser.CheckAPI();
else
parser.NextToken();
}

parser.DumpTypes();

parser.Close();

return 0;
}
yyyapple 2009-03-24
  • 打赏
  • 举报
回复
//袁峰在W32图形编程书里写的parser,可以参考下
//-----------------------------------------------------------------------------------//
// Windows Graphics Programming: Win32 GDI and DirectDraw //
// ISBN 0-13-086985-6 //
// //
// Written by Yuan, Feng www.fengyuan.com //
// Copyright (c) 2000 by Hewlett-Packard Company www.hp.com //
// Published by Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com //
// //
// FileName : skimmer.cpp //
// Description: Simple parser for Win32 header file //
// Version : 1.00.000, May 31, 2000 //
//-----------------------------------------------------------------------------------//

#define STRICT
#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <stdio.h>


class KParser
{
typedef enum { MAX_TYPES = 512,
MAX_NAMELEN = 64
};
HANDLE str;
HANDLE hmap;
char * view;

unsigned int size;
unsigned int pos;

char typnam[MAX_TYPES][MAX_NAMELEN];
int types;

public:

bool Open(const char * file)
{
str = CreateFile(file,
GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);

if ( str == INVALID_HANDLE_VALUE )
return false;

size = GetFileSize(str, NULL);

hmap = CreateFileMapping(str, NULL, PAGE_READONLY, 0, 0, NULL);

if ( hmap )
view = (char *) MapViewOfFile(hmap, FILE_MAP_READ, 0, 0, 0);

ch = ' ';
pos = 0;

types = 0;

return true;
}

char ch;
char token[MAX_PATH];

void Close(void)
{
UnmapViewOfFile(view);
CloseHandle(hmap);
CloseHandle(str);
}

bool Eof(void)
{
printf("%d - %d\n", pos, size);
return pos >= size;
}

bool Equal(const char *check);

void Nextch(void);
void NextToken(void);

void CheckType(char *word);
void CheckTypes(char * line);
void DumpTypes();

void CheckAPI(void);
};


void KParser::CheckType(char * word)
{
while ( * word==' ' )
word ++;

int len = strlen(word);

while ( len && word[len-1]==' ' )
{
len --;
word[len]=0;
}

if ( len==0 )
return;

for (int i=0; i<types; i++)
if ( strcmp(word, typnam[i])==0 )
return;

strcpy(typnam[types], word);
types ++;
}


void KParser::DumpTypes(void)
{
printf("\n");
printf("[Types]\n");

for (int i=0; i<types; i++)
{
printf(typnam[i]);
printf("\n");
}
}


// type func(t1,t2,...tn)
// ^15
void KParser::CheckTypes(char * line)
{
line[14] = 0;

CheckType(line);

line = strchr(line+15, '(');

if ( line )
{
line ++;
char * p;

while ( p = strchr(line, ',') )
{
* p = 0;
CheckType(line);

line = p+1;
}

p = strchr(line, ')');

if ( p )
{
* p = 0;
CheckType(line);
}
}
}


void KParser::Nextch(void)
{
do
{
ch = * view ++;
pos ++;
}
while (ch=='\r'); // skip '\r'

if ( ch=='\t' )
ch=' '; // map tab to space
}


void KParser::NextToken(void)
{
again:
token[0] = 0;

if ( Eof() )
return;

while ( ch==' ' )
Nextch();

if ( ch=='\n' )
{
token[0] = ch;
token[1] = 0;

Nextch();
return;
}

if ( ch=='/' )
{
Nextch();

if ( ch=='/' ) // single line commented
{
while ( ch!='\n')
Nextch();
Nextch();
goto again;
}

if ( ch=='*' ) // block comment /* ... */, nesting not allowed
{
Nextch();

more:
while ( ch!='*')
Nextch();

Nextch();
if ( ch=='/' )
{
Nextch();
goto again;
}
else
goto more;
}

token[0] = '/';
token[1] = 0;

return;
}

int len = 0;

// simple single character delimiters
switch ( ch )
{
case '(':
case ')':
case ',':
case ';':
case '[':
case ']':
case '+':
case '*':
token[len++] = ch;
token[len] = 0;
Nextch();
return;
}

// identifiers or keywords
if ( (ch=='_') || isalpha(ch) )
{
token[len++] = ch;
Nextch();

while ( (ch=='_') || isalpha(ch) || isdigit(ch) )
{
token[len++] = ch;
Nextch();
}

token[len] = 0;
return;
}

// others
while ( (ch!=' ') && (ch!='\n') )
{
token[len++] = ch;
Nextch();
}

token[len] = 0;
}


bool KParser::Equal(const char * check)
{
return strcmp(token, check)==0;
}

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧