0

我正在解析一个 SCPI 字符串,它看起来像:

HEADER:HEADER:HEADER:CMD NUMBER MULTIPLIER UNIT;

标记 NUMBER、MULTIPLIER 和 UNIT 之间的空格不一定存在,也不一定存在固定长度的标记。我已经能够解析(从 L 到 R)直到 NUMBER 的末尾。但是,MULTIPLIER 和 UNIT 标记都是可选的,并且可以具有相同的字符。

例如,后缀可以是“P”(其中 P 可以表示 pico [mult] 或 poise [unit])

或“MA”(可以是兆 [mult] 或毫安 [mult-unit])

有没有人有任何解析这种语法的经验,或者实际上有其他人对如何将它们解析成正确的标记有任何想法。

编辑:对于学究,我想这是比解析更多的词法分析。

4

1 回答 1

1

也许在您的简单示例中,使用几个嵌套if的 s 会比尝试更强大的方法更容易,但如果您不想手动执行此操作,或者实际问题有点大,您可以尝试匹配您的使用正则表达式输入(标准词法分析器的东西)。

在 POSIX 系统上,您可以使用regexec.

编辑:如何使用if(和select):

我假设你的输入是 intext并且你已经读到了 NUMBER 的末尾,所以你的 indexi表明了这一点!

// helper function: find next non-whitespace character
char get_prev(char *text, int *end, int i)
{
    for (; *end > i; --*end)
        if (text[*end] != ' ' && text[*end] != '\t'
            && text[*end] != '\n' && text[*end] != '\r')
        // or `if (text[*end] > ' ')` if ASCII
            break;
    return text[(*end)--];
}

... your function...
    // read up to i
    int end = strlen(text);
    int power_of_10 = 0;  // for MULT
    enum unit unit = UNKNOWN; // for UNIT
    switch (get_prev(text, &end, i))
    {
        case 'P':
            unit = POISE;
            break;
        case 'A':
            unit = AMP;
            break;
        ...
        default: // unforeseen character
        case '\0':
            // neither UNIT nor MULT exist
            break;
    }
    if (unit != UNKNOWN)
        switch (get_prev(text, &end, i))
        {
            case 'M':
                power_of_ten = -3;  // milli
                break;
            case 'A':
                switch (get_prev(text, &end, i))
                {
                    case 'M':
                        power_of_ten = 6;  // mega
                        break;
                    ...
                }
                break;
            ...
            default: // unforeseen character
            case '\0':
                // MULT doesn't exist
                break;
        }

Note, in this case, I assumed UNIT is mandatory. I'm not sure how you can distinguish between mega and milliamp in 10MA if both MULT and UNIT are optional. However you can add more cases to the first switch, that correspond to values of MULT and change power_of_10 there to. For example, if in the first switch you see k, you can understand that UNIT doesn't exist and power_of_10 is 3.

于 2012-07-23T16:15:25.733 回答