2012-10-18 168 views
1

我想要的输出作为如何在lex和yacc中读取多行输入?

a=3 mov a,3 
a=fs mov b,fs 
b=32 mov b,32 

程序3个地址中间代码生成: 该法文件进行词法分析编写的,从读取命令行输入并传递令牌:

%{ 
#include "y.tab.h" 
#include "string.h" 
#include <math.h> 
%} 
%% 
[a-zA-Z]+ { yylval.var=(char *)malloc(sizeof(char *)); 
      strcpy(yylval.var,yytext); 
     return ID;} 
"="  return EQUALS; 
[0-9]+ {yylval.num=atoi(yytext);return DIGIT;} 


%% 

的YACC文件:

%{ 

#include "stdio.h" 

#include "string.h" 

int yywrap() 
{ 
return 1; 
} 
%} 


%union 
{char *var; 
int num; 
} 


%token <var> ID 
%token <num> EQUALS DIGIT 




%% 
start : line 

line : ID EQUALS DIGIT {printf("MOV %s, %d\n",$1, $3);} 
    | ID EQUALS ID {printf("MOV %s, %s\n",$1, $3);} 
    ; 


%% 

main() 

{ 

yyparse(); 

return 0; 

} 

int yyerror(char *s) 

{ 
fprintf(stderr,"%s\n",s); 

} 

现在,作为运行上面的代码(lex和yacc之间的链接)的输出

dsa=32     
MOV dsa, 32    // 3 address code generated 

ds=342      // but does not parse this line why?? 
syntax error 
+1

这里还有其他几个问题。你是malloc() - 一个字节,但你正在复制一个任意长度的标识符。你可以使用'yylval.val = strdup(yytext);'这里。您不需要定义标记名称并为所有特殊字符编写特殊规则:它是Hercules的一项工作。取而代之的是yylex.l'中的最后一行。返回yytext [0];'只需在语法中直接使用特殊字符,例如如'='。这也有非法字符进入解析器错误恢复系统的优势,因此您不必在词法层面处理它们。 – EJP

回答

3

你的语法只读取单个line

也许你想:

start : line 
     | start line 
     ; 
2

不清楚你想要什么。你想要一个电话yyparse解析多行(一切,直到你得到一个EOF)?如果是这样,rici的答案就是你想要的。或者你想yyparse解析一行并返回,之后你可以再次调用它来解析另一行?如果这是你想要什么,你需要让你的词法分析器去识别新行并返回他们的EOF:

[\n] return -1; 

然而,当前的语法,这会给你的空行语法错误,可能会或可能不会成为你想成为的人。