2012-03-13 65 views
1

我在头文件中定义了一些常量,这些常量包含由flex/bison中写入的文件解析器解析的某些字符串的最大长度。我想将检查字符串长度的代码从c代码移到我的正则表达式中,以使事情更简洁一些。在flex规则中使用外部定义的常量

现在我有一个看起来像规则:

[[:alnum:]]+ { yylval.sval = (char*) strdup(yytext); return STRING; } 

凡长度检查发生在野牛规则。

我想修改这一点,以便它检查比赛比MAX_STR_LEN不再这是在头叫constants.h定义。如果MAX_STR_LEN等于32,比我想同样的效果:

[[:alnum:]]{1,32} 

反正有没有做到这一点无需经过预处理的额外步骤运行我的Flex文件?

编辑:

下面的规则将失败,因为MAX_STR_LEN不是文字数,它被看作是一个字符串,因此柔性认为2个行动已经为一个规则定义。

[[:alnum:]]{1,MAX_STR_LEN} { do_something(); } 

另外如果试图向限定在flex文件的声明部分的宏比它也失败本身。

max_len 32 /* Also fails if 32 is replaces with MAX_STR_LEN */ 
%% 
[[:alnum:]]{1,max_len} { do_something(); } 

回答

2

你可以在动作规则处理它:

[[:alnum:]]+ { if (yyleng > MAX_STR_LEN) yyless(MAX_STRING_LEN); 
        yylval.sval = (char*) strdup(yytext); return STRING; } 

这使得规则有效地与您的{1,MAX_STR_LEN}修改器我已经包括常量头图案

+0

请注意,如果您执行了上述'yyless',则您将重新扫描作为另一个'STRING'标记的多余部分,给出扫描仪中的其他功能。这实际上是原始问题的问题,但至少可以说,将ABCDEFG作为三个单独的字符串ABC,DEF,G(使用3作为此示例的最大值)是非常不寻常的。 (这也是低效率的,但是再次,所以呢?) – torek 2012-03-22 19:15:43

+0

这可能是最接近我最初问的。我确实决定采取这种方法,因为它看起来更灵活一些。 – msikora 2012-03-24 21:41:28

1

Flex生成一个C源文件。在这个C源文件的顶部是“任意的C代码”,你自己写的:

%{ 
whatever you like goes here 
%} 

由于这个生成的代码之前出来,你可以#include "constants.h"并访问您的宏。您也#include <string.h>,可以strdup之前,只要你不限制自己严格的POSIX沟投(如果你在图书馆有strdup可言,你可能有它在string.h)。

+0

。问题是正则表达式。如果我尝试 '[[:alnum:]] {1,MAX_STR_LEN} {do_something(); }' 它失败,因为MAX_STR_LEN不是一个数字,它认为我为单个规则定义了2个动作。 – msikora 2012-03-14 00:48:03

+0

哦。呃,对不起,误解了你的问题!唉,不,你不能让RE解析器来做到这一点。无论如何,这可能不是一个好主意,因为它意味着33个字符的字母数字根本不会是一个有效的标记。在决定它是一个有效的标记之后,但在返回之前,即在设置yylval并返回一个标记号码的代码之内,你有什么理由不能做这个开关?只要返回TOOLONG_STRING len> max。这给你一个把解析器中的错误处理器放在一个好地方。 – torek 2012-03-14 00:57:38

+0

我只是打算解析器失败,如果字符串太长,但为无效字符串添加标记也可能会有所帮助。感谢您的快速响应。 – msikora 2012-03-14 01:04:53

0

不,由flex生成的扫描器设置得很好,不能在运行时更改。除了在torek的回答(if (strlen (yytext) > MAX_STR_LEN) return TOOLONG_STRING;)的评论中讨论的选项之外,另一个更复杂的可能性是使用启动条件和临时缓冲区等自己完成字符串累加,并且如果发现超过MAX_STR_LEN个字符,则表示发生错误,但很难想象这是值得努力的场景。

完全无关,我会考虑是否真的有一个令人信服的理由来限制长度。一旦你设计你的程序的时候,假定“弦永远不会超过MAX_STR_LEN”,这很难改变装备。如果您以“字符串可以是任意长度”的要求开始,代码并不复杂得多,但您获得了很大的灵活性。