在c和正则表达式中使用flex

时间:2015-02-06 14:52:59

标签: c regex compiler-construction flex-lexer lexical-analysis

我正在尝试为编译器创建一个词法分析器。但是我在使用正则表达式查找关键字和实数等问题时遇到了问题..例如一些定义:

id         [aA-zZ][aA-zZ-0-9_]* 

keyword    if|else|when|while

integer    [0-9]+

real       integer\.integer

..虽然存在一些问题,但分析师无法获得关键字,例如,如果我给出“' else'它认为它是一个id(我得到一个像规则一样的警告也不能匹配。

此外,如果我尝试给出一个实数,例如1.2 链接器将其视为整数分隔符整数,而不是真实的。虽然我不擅长regural表达式语言,但我认为真实/整数的区别是要设置一个规则("读取一个没有&#39的数字) ; t结束。并且它是一个整数,否则它是一个数字")但我怎么能把它放在reg中。语言。

2 个答案:

答案 0 :(得分:4)

Flex没有检测到所需字符串的原因是读取输入时存在歧义。 “' else'对应于正则表达式"否则"和[a-zA-Z] [a-zA-Z0-9] *,但最后一个是首先编写的,所以Flex决定输入必须符合这个正则表达式。

Flex是一个词法分析器,它读取输入文件并使用您希望它检查的任何正则表达式检查当前字符串。你必须始终记住驱动其字符串匹配系统的两个基本规则:

  • 最长的最佳匹配;
  • 优先规则;

'最长的最佳匹配'告诉Flex,读取输入必须与可能的最长模式匹配; LBM规则优先工作得更好。

优先级规则告诉Flex,如果输入匹配多于一个正则表达式,则只能考虑第一个正则表达式。

在编写代码时,必须将关键字视为关键字而不是ID,然后您应该编写关键字'正则之前的正则表达式:如果某些东西不匹配关键字'正则表达式,这意味着我们正在阅读其他内容,如id或函数名称。

我会写这样的东西:

keyword     "if"|"else"|"when"|"while"
id          [a-zA-Z][a-zA-Z0-9_-]*
nat         [0-9]|([1-9][0-9]*)
integer     [+|-]*{nat}
real        {integer}[.]{integer}

关键字优先;如果我们不读取关键字,它可能是一个id;如果只有数字,让我们看看它是什么类型的数字。 优先规则会让Flex阅读“其他”,“如果'和其他关键字'关键字'代币和最长的最佳匹配将确保像1.2这样的数字将被认为是真实的'而不是两个' nat'用点分隔。

答案 1 :(得分:3)

当相同的词汇可以由多个规则匹配时,lex选择文件中首先出现的那个。因此,关键字的规则必须先于标识符。

规则integer.integer的问题不在于它不能从整数规则中消除歧义 - 事实上,由于根本没有重叠,因此可以消除歧义。问题是它匹配字符串"整数",后跟任何字符,后跟字符串"整数"。您无法引用规则中的其他规则。您可以使用花括号创建定义并引用它,或者只需编写[0-9]+ '.' [0-9]+