2016-11-09 70 views
-2

我必须写有这些规则lex程序:如何识别ID,和注释中莱克斯文件

Identifiers: String of alphanumeric (and _), starting with an alphabetic character

Literals: Integers and strings

Comments: Start with ! character, go to until the end of the line

这是我与

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

上来然而,我编译这个lex文件时仍然会出现很多错误。

您认为错误是什么?

回答

0

如果你更清楚地表明了你的代码出现了什么问题,它会有所帮助。例如,您是否收到错误消息或者没有按照需要运行?

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

如果我们通过把法代码我们会得到这个错误:

"SoNov16.l", line 1: bad character: [
"SoNov16.l", line 1: unknown error processing section 1
"SoNov16.l", line 1: unknown error processing section 1
"SoNov16.l", line 1: bad character: ]
"SoNov16.l", line 1: bad character: +
"SoNov16.l", line 1: unknown error processing section 1
"SoNov16.l", line 1: bad character: (
"SoNov16.l", line 1: unknown error processing section 1
"SoNov16.l", line 1: bad character:)
"SoNov16.l", line 1: bad character: ;

你收到类似的东西?在您的示例代码中,您指定了操作(return(ID);是操作的一个示例),因此您的代码用于第二部分。因此您需要在其之前放置一条%%。这将是一个有效的lex程序。

您的代码依赖于(可能)解析器,该解析器会消耗(并声明)令牌。出于测试目的,首先打印令牌通常更容易。我解决了这个问题,通过制作一个可以完成打印的宏,并且可以重新定义在稍后阶段执行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
String: abc Matched: ID

abc123
String: abc123 Matched: ID

! comment text
String: ! comment text
Matched: COMMENT

不完全正确。我们可以看到ID规则匹配应该是一个字符串。这是由于规则的排序。我们必须先将字符串规则放在第一位,以确保它首先匹配 - 除非您应该在某些引号内匹配字符串?你也错过了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
String: abc Matched: STRING
abc123_
String: abc123_ Matched: ID
-1234
String: -1234 Matched: INTEGER
abc abc123 ! comment text
String: abc Matched: STRING
String: abc123 Matched: ID
String: ! comment text
Matched: COMMENT

万一你想在引号中的字符串,这是一件容易的事:

%{ 
#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"
String: "abc" Matched: STRING