C Tokenizer - 它是如何工作的?

时间:2010-07-30 14:36:53

标签: c algorithm tokenize

这是如何运作的?

我知道你用它来传递:

  • start:string(例如“第1项,第2项,第3项”)
  • delim:分隔符字符串(例如“,”)
  • tok:引用一个包含令牌的字符串
  • nextpos(可选):引用原始字符串中下一个标记开始的位置
  • sdelim(可选):指向将保存令牌
  • 的起始分隔符的字符的指针
  • edelim(可选):指向将保存令牌结束分隔符的字符的指针

代码:

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

int token(char* start, char* delim, char** tok, char** nextpos, char* sdelim, char* edelim) {
    // Find beginning:
    int len = 0;
    char *scanner;
    int dictionary[8];
    int ptr;

    for(ptr = 0; ptr < 8; ptr++) {
        dictionary[ptr] = 0;
    }

    for(; *delim; delim++) {
        dictionary[*delim / 32] |= 1 << *delim % 32;
    }

    if(sdelim) {
        *sdelim = 0;
    }

    for(; *start; start++) {
        if(!(dictionary[*start / 32] & 1 << *start % 32)) {
            break;
        }
        if(sdelim) {
            *sdelim = *start;
        }
    }

    if(*start == 0) {
        if(nextpos != NULL) {
            *nextpos = start;
        }
        *tok = NULL;
        return 0;
    }

    for(scanner = start; *scanner; scanner++) {
        if(dictionary[*scanner / 32] & 1 << *scanner % 32) {
            break;
        }
        len++;
    }

    if(edelim) {
        *edelim = *scanner;
    }

    if(nextpos != NULL) {
        *nextpos = scanner;
    }

    *tok = (char*)malloc(sizeof(char) * (len + 1));

    if(*tok == NULL) {
        return 0;
    }

    memcpy(*tok, start, len);
    *(*tok + len) = 0;


    return len + 1;
}

我得到的大部分内容除了:

dictionary[*delim / 32] |= 1 << *delim % 32;

dictionary[*start / 32] & 1 << *start % 32

这是魔术吗?

3 个答案:

答案 0 :(得分:4)

由于分隔符的每个字符都是8位(sizeof(char) == 1字节),因此它限制为256个可能的值。

字典分为8个部分(int dictionary[8]),每个部分有32种可能性(sizeof(int)是&gt; = 4个字节)和32 * 8 = 256。

这形成了256位的值矩阵。然后它会打开分隔符(dictionary[*delim / 32] |= 1 << *delim % 32;)中每个字符的标志。数组的索引是*delim / 32,或者字符的ASCII值除以32.由于ASCII值的范围是0到255,因此该除数产生的值为0到7,其余为余数。剩下的是要打开的位,由模数运算决定。

如果分隔符中存在相应的ASCII字符,则所有这一切都将256位矩阵的某些位标记为true。

然后确定字符是否在分隔符中只是在256位矩阵中查找(dictionary[*start / 32] & 1 << *start % 32

答案 1 :(得分:1)

它们通过在字典中存储8 x 32 = 256位表来存储发生了哪些字符。

dictionary[*delim / 32] |= 1 << *delim % 32;

设置与* delim

对应的位
dictionary[*start / 32] & 1 << *start % 32

检查位

答案 2 :(得分:0)

好的,如果我们为","发送字符串delimiter,那么dictionary[*delim / 32] |= 1 << *delim % 32将为dictionary[1] = 4096。表达式dictionary[*start / 32] & 1 << *start % 32只是检查匹配的字符。

令我困惑的是他们没有使用直接char比较的原因。

相关问题