如何识别Lex文件中的ID,文字和注释

时间:2016-11-09 17:19:08

标签: lex lexical-analysis

我必须编写一个包含以下规则的lex程序:

  

标识符:字母数字字符串(和_),以字母字符开头

     

文字:整数和字符串

     

评论:从!字符开始,一直到行尾

这是我提出的

[a-zA-Z][a-zA-Z0-9]+    return(ID);
[+-]?[0-9]+     return(INTEGER); 
[a-zA-Z]+    return ( STRING);
!.*\n                  return ( COMMENT ); 

但是,当我编译这个lex文件时,我仍然会遇到很多错误。

您认为错误是什么?

1 个答案:

答案 0 :(得分:0)

如果您更清楚地了解代码的问题,那会有所帮助。例如,您是否收到错误消息或未按预期运行?

您的代码存在一些问题,但主要是正确的。我看到的第一个问题是你没有将你的lex程序划分为%%分隔符所需的部分。 lex程序的第一部分是声明部分,其中指定了正则表达式模式。第二部分是指定匹配模式的操作的位置。 (可选)第三部分是放置任何代码(用于编译器)的地方。编译器的代码也可以放在声明部分,在行的开头由%{%}描述。

如果我们将代码放入lex,我们会收到此错误:

  

" SoNov16.l",第1行:坏人:[
  " SoNov16.l",第1行:未知错误处理部分1
  " SoNov16.l",第1行:未知错误处理部分1
  " SoNov16.l",第1行:坏人:]   " SoNov16.l",第1行:坏字符:+
  " SoNov16.l",第1行:未知错误处理部分1
  " SoNov16.l",第1行:坏人:(
  " SoNov16.l",第1行:未知错误处理部分1
  " SoNov16.l",第1行:坏人物:)   " SoNov16.l",第1行:坏人物:;

你有没有这样的东西?在您的示例代码中,您指定了操作(return(ID);是操作的示例),因此您的代码用于第二部分。因此,您需要在其前面加上%%行。那将是一个有效的lex计划。

您的代码依赖于(可能)解析器,它使用(并声明)令牌。出于测试目的,首先打印令牌通常更容易。我通过制作一个 C 宏来解决这个问题,该宏将执行打印并可以在以后阶段重新定义以执行return。像这样:

%{
#define TOKEN(t) printf("String: %s Matched: " #t "\n",yytext)
%}
%%
[a-zA-Z][a-zA-Z0-9]+    TOKEN(ID);
[+-]?[0-9]+     TOKEN(INTEGER); 
[a-zA-Z]+    TOKEN (STRING);
!.*\n                  TOKEN (COMMENT); 

如果我们构建并测试它,我们会得到以下结果:

  

ABC
  字符串:abc符合次数:ID

     

ABC123
  字符串:abc123符合次数:ID

     

!评论文本
  字符串:!评论文本
  匹配:评论

不太正确。我们可以看到ID规则匹配应该是字符串。这是由于规则的排序。我们必须首先放置String规则以确保它首先匹配 - 除非你当然应该匹配某些引号内的字符串?您还错过了ID模式的下划线。匹配和丢弃任何空格字符也是一个好主意:

%{
#define TOKEN(t) printf("String: %s Matched: " #t "\n",yytext)
%}
%%
[a-zA-Z]+                TOKEN (STRING); 
[a-zA-Z][a-zA-Z0-9_]+    TOKEN(ID);
[+-]?[0-9]+              TOKEN(INTEGER);
!.*\n                    TOKEN (COMMENT);
[ \t\r\n]+               ;

测试时显示:

  

ABC
  字符串:abc符合条件:字符串
  abc123_
  字符串:abc123_符合次数:ID
  -1234
  字符串:-1234符合条件:INTEGER
  abc abc123!评论文本
  字符串:abc符合条件:字符串
  字符串:abc123符合次数:ID
  字符串:!评论文本
   匹配:评论

万一你想要引号中的字符串,这也很容易:

%{
#define TOKEN(t) printf("String: %s Matched: " #t "\n",yytext)
%}
%%
\"[^"]+\"    TOKEN (STRING); 
[a-zA-Z][a-zA-Z0-9_]+    TOKEN(ID);
[+-]?[0-9]+     TOKEN(INTEGER);
!.*\n                  TOKEN (COMMENT ); 
[ \t\r\n]         ;
  

" ABC"
  字符串:" abc"匹配:STRING