Flex / Bison:标记化由空格/制表符分隔的关键字的通用方法

时间:2015-03-12 12:09:05

标签: regex compiler-construction bison flex-lexer

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

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]模式而在多行中键入命令。

2 个答案:

答案 0 :(得分: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.

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

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

答案 1 :(得分:0)

分离器是否包含在词汇中是否重要?通常它不是,我们可以放弃任何分隔符,留下代币本身的参数:

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