使C解析器高效 [英] Making C parser efficient

查看:79
本文介绍了使C解析器高效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define CliMaxSize 1024
#define PacketMaxSize 999  
#define MaxNumberofPackets 5 


#if 1

static char InData[CliMaxSize] = "\r\nRCV\r\nSOME:DATA40\r\n24Ab2bfsdfa46jKjj936100dsasgdfsdf1240s0x\r\nOK\r\n\r\nRCV\r\nSOME:DATA50\r\n24Ab246324400123543gfdsas4sdaasd22231fn67sdff46ngk\r\nOK\r\n\r\nRCV\r\nSOME:DATA0\r\n\r\nOK\r\n";
#endif


#if 0

static char InData[CliMaxSize] = "\r\nRCV\r\nSOME:DATA40\r\n24Ab2bfsdfa46jKjj936100dsasgdfsdf1240s0x\r\nOK\r\n\r\nRCV\r\nSOME:DATA60\r\n24Ab246324400123543gfdsas4sdaasd";
#endif

static char PacketBytes[PacketMaxSize];

typedef struct {
    unsigned char ValidPackets;
    unsigned char DataSizeStartAddress[MaxNumberofPackets];
    unsigned char ValidPacketsStartAddress[MaxNumberofPackets];
    unsigned int DataSize[MaxNumberofPackets];
}_CLI;


static unsigned char AvailableValidPackets(_CLI *const PtrCLI) {
    char *pch;
    PtrCLI->ValidPackets = 0;
    pch = strstr(InData,"OK\r\n");
    while (pch != NULL) {
        PtrCLI->ValidPackets++;
        pch = strstr(++pch,"OK\r\n");
    }
    return PtrCLI->ValidPackets;
}

static void GetStartAddressOfPackets(_CLI *const PtrCLI) {
    char *pch = &InData[0];
    unsigned char LocalCounter = 0;
    /* find the location of ":" in Source */
    while (*pch++ != '\0') {
        if (*pch == ':') {
            PtrCLI->ValidPacketsStartAddress[LocalCounter] = pch - &InData[0] + 9;
            PtrCLI->DataSizeStartAddress[LocalCounter] = pch - &InData[0] + 5;
            LocalCounter++;
        }
    }
}

static void ExtractDataSizeInIntegerForm(_CLI *const PtrCLI) {
    char LocArray[MaxNumberofPackets] = { 0,0,0,0,0};
    char LocCounter = 0, LocalDummy = 0, localMultiplier = 1;

    for (char LocLoop = 0; LocLoop < PtrCLI->ValidPackets; LocLoop++) {
        char *LocPtr = (char*)&InData[PtrCLI->DataSizeStartAddress[LocLoop]];
        while (*LocPtr != '\r') {
            LocArray[LocCounter++] = *(LocPtr++) - '0';
            localMultiplier *= 10;
        }
        for (char c = 0; c < LocCounter; c++){
            localMultiplier = localMultiplier / 10;
            LocalDummy += LocArray[c] * localMultiplier;
            LocArray[c] = 0;
        }
        PtrCLI->DataSize[LocLoop] = LocalDummy;
        LocCounter = 0;
        LocalDummy = 0;
    }
}

static void CopyString(const int StartAddress, const int size) {
    char *ptr = &InData[0] + StartAddress;
        memset(PacketBytes, '\0', sizeof(PacketBytes));
        for(char i = 0; i < size; i++) {
            PacketBytes[i] = *ptr++;
        }

}

static void ExtractPackets (_CLI *const PtrCLI){
    for(char i = 0; i< PtrCLI->ValidPackets; i++) {
	if (PtrCLI->DataSize[i] != 0) {
	CopyString(PtrCLI->ValidPacketsStartAddress[i], PtrCLI->DataSize[i]);
        printf("Packet %d> size: %d data: ",i+1, PtrCLI->DataSize[i]);
		for (char j = 0; j< PtrCLI->DataSize[i]; j++)
			{
				printf("%c", PacketBytes[j]);
			}
		printf("\n");
    }
else {
	printf("Packet %d> size: %d data: \n",i+1, PtrCLI->DataSize[i]);
	}
}
}

int main() {
    _CLI CommandLineInterface;
    AvailableValidPackets(&CommandLineInterface);
    GetStartAddressOfPackets(&CommandLineInterface);
    ExtractDataSizeInIntegerForm(&CommandLineInterface);
    ExtractPackets(&CommandLineInterface);
    return 0;
}





我的尝试:



我正在制作这个解析器并根据需要输出:

数据包1>尺寸:40数据:24Ab2bfsdfa46jKjj936100dsasgdfsdf1240s0xPacket 2>尺寸:50数据:24Ab246324400123543gfdsas4sdaasd22231fn67sdff46ngkPacket 3>大小:0数据:

但我的主管要求我提高效率。你们中的任何人都可以提出一些建议,让它变得更好更短吗?

任何建议都将受到赞赏。



What I have tried:

I am making this parser and the output is as required:
Packet 1> size: 40 data: 24Ab2bfsdfa46jKjj936100dsasgdfsdf1240s0x
Packet 2> size: 50 data: 24Ab246324400123543gfdsas4sdaasd22231fn67sdff46ngk
Packet 3> size: 0 data:
but my supervisor is asking me to make it more efficient. can anyone of you give some suggestions to make it better and short?
any suggestion will be appreciated.

推荐答案

你可以结合 AvailableValidPackets GetStartAddressOfPackets 很容易。另外要对它进行更优化,对所有输入数据进行一次迭代,而不是使用strstr,并一次性进行解析,计数等。
You can combine AvailableValidPackets and GetStartAddressOfPackets easily. Also to optimized it more, have one single iteration over all input data instead of using strstr and do parsing, counting etc. in one go.


Quote:

static void CopyString(const int StartAddress,const int size){

char * ptr =& InData [0] + StartAddress;

memset(PacketBytes,'\ 0',sizeof(PacketBytes));

for(char i = 0; i< size; i ++){

PacketBytes [i] = * ptr ++;

}



}

static void CopyString(const int StartAddress, const int size) {
char *ptr = &InData[0] + StartAddress;
memset(PacketBytes, '\0', sizeof(PacketBytes));
for(char i = 0; i < size; i++) {
PacketBytes[i] = *ptr++;
}

}



我看不到为了将 PacketBytes 缓冲区置零,代码会立即覆盖它。


I see no purpose in zeroing the PacketBytes buffer, the code is immediately overwriting it.


这篇关于使C解析器高效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆