2012-10-18 204 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; 

然而,當前的語法,這會給你的空行語法錯誤,可能會或可能不會成爲你想成爲的人。