【问题标题】:Flex/Bison : Generic way to tokenize keywords separated by whitespaces/tabsFlex/Bison:用空格/制表符分隔关键字的通用方法
【发布时间】:2015-03-12 12:09:05
【问题描述】:

我正在编写一个程序,它允许命令(基本上是一个直到换行符的字符串)包含多个以空格分隔的参数。

Like: arg1 arg2 arg3 arg4 (\n)

我可以使用正则表达式本身来实现这一点,如下所示:

arg1[ \t]+    {return T_ARG1;}
arg2[ \t]+    {return T_ARG2;}
arg3[ \t]+    {return T_ARG3;}
arg4[ \t]+    {return T_ARG4;}

但我不确定这样做是不是最好的方法? 您能否在 Flex 中提出一种通用的方法?

注意:我还允许通过忽略 [\\n] 模式来跨多行键入命令。

【问题讨论】:

  • 参数真的是关键字吗?还是它们是任意空格分隔的单词?换句话说,您是在尝试以任意顺序识别一组固定单词,还是按照输入顺序创建参数向量?
  • 是的,我正在尝试以某种顺序识别一组固定单词。
  • 我正在尝试使用 flex 和 bison 创建一个命令(如 linux 命令)解释器。顺序为:arg1 arg2 arg3 arg4 注意: 表示最少一个空格。

标签: regex compiler-construction bison flex-lexer


【解决方案1】:

使用arg1[ \t]+ 不是一个好主意,因为您正在返回一个“脏”标记 - 您想要的带有多余空格的标记,您可能希望稍后删除它们(这意味着更多的解析)。

记住 flex 是贪婪的:

If it finds more than one match, it takes the one matching the most text (for trailing context rules, this includes the length of the trailing part, even though it will then be returned to the input). If it finds two or more matches of the same length, the rule listed first in the flex input file is chosen.

所以它会尝试匹配最大的文本,并且在长度相等的情况下会考虑模式顺序only。所以你需要优先考虑你的参数,然后放置一个匹配其余单词的模式:

WHITESPACE    [\t\n\r ]
DIGIT         [0-9]
LETTER        [a-zA-Z]
%%
arg1                  return T_ARG1;
arg2                  return T_ARG2;
arg3                  return T_ARG3;
arg4                  return T_ARG4;
(LETTER|DIGIT|[_])+   printf("error! unknown command\n");
WHITESPACE            ;
%%

您可以使用[:digit:] 或仅使用[0-9] 而不是我定义的DIGIT,有关更多标准表达式,请参阅here

【讨论】:

    【解决方案2】:

    在词位中包含分隔符是否重要?通常不是这样,我们可以丢弃任何分隔符,将标记留给参数本身:

    [ \t\n\r]+      ; /* Skip */
    arg1        return T_ARG1;
    arg2        return T_ARG2;
    arg3        return T_ARG3;
    arg4        return T_ARG4;
    

    【讨论】:

    • 例如,ip addradd(inux 给我一个错误)对象“addradd”是未知的,试试“ip help”。因为 addr 和 add 之间必须有一个空格。
    • 我也试过你的代码。但它也接受我不想要的 arg1arg2arg3arg4。我希望两个单词之间至少有一个空格。
    猜你喜欢
    • 2016-08-05
    • 2017-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多