执行使用lex和yacc工具开发的c文件时出错

时间:2014-04-06 08:49:51

标签: c compiler-construction yacc lex

我正在尝试使用lex和yacc.So设计一个mini c编译器。当我使用输入c文件编译它时,它表明c文件中有语法错误,即使c文件没有任何错误。

LEX FILE(c.l)

   %{
   #include"y.tab.h"
   int line=0;
   %}

   alpha [a-zA-Z]
   digit [0-9]

   %%
   [ \t]        ;
   [ \n]   {line++;}
    int        { return INT;}
   float    {return FLOAT; }
   char     {return CHAR;}
   void     {return VOID;}
   double   {return DOUBLE;}
   for  {return FOR;}
   while    {return WHILE;}
   if   {return IF;}
   else {return ELSE;}
   printf {return PRINTF;}
   struct   {return STRUCT;}
   ^"#include ".+ ;
   {digit}+ { return NUM;}
   {alpha}({alpha}|{digit})* {return ID;}
   "<="    {return LE;}
   ">="    {return GE;}
   "=="    {return EQ;}
   "!="    {return NE;}
   ">"  {return GT;}
   "<"  {return LT;}
   "."     {return DOT;}
   \/\/.* ;
   \/\*(.*\n)*.*\*\/ ;
   .       return yytext[0];
   %%

YACC文件(c.y):

     %{
      #include <stdio.h>
      #include <stdlib.h>


      extern FILE *fp;

      %}

      %token INT FLOAT CHAR DOUBLE VOID
      %token FOR WHILE 
      %token IF ELSE PRINTF 
      %token STRUCT 
      %token NUM ID
      %token INCLUDE
      %token DOT

      %right '='
      %left AND OR
      %left '<' '>' LE GE EQ NE LT GT
      %%

      start:    Function 
 | Declaration
;

    /* Declaration block */
    Declaration: Type Assignment ';' 
| Assignment ';'    
| FunctionCall ';'  
| ArrayUsage ';'    
| Type ArrayUsage ';'   
| StructStmt ';'    
| error 
;

     /* Assignment block */
     Assignment: ID '=' Assignment
| ID '=' FunctionCall
| ID '=' ArrayUsage
| ArrayUsage '=' Assignment
| ID ',' Assignment
| NUM ',' Assignment
| ID '+' Assignment
| ID '-' Assignment
| ID '*' Assignment
| ID '/' Assignment 
| NUM '+' Assignment
| NUM '-' Assignment
| NUM '*' Assignment
| NUM '/' Assignment
| '\'' Assignment '\''  
| '(' Assignment ')'
| '-' '(' Assignment ')'
| '-' NUM
| '-' ID
|   NUM
|   ID
;

    /* Function Call Block */
    FunctionCall : ID'('')'
| ID'('Assignment')'
;

     /* Array Usage */
     ArrayUsage : ID'['Assignment']'
;

    /* Function block */
    Function: Type ID '(' ArgListOpt ')' CompoundStmt 
;
    ArgListOpt: ArgList
|
;
    ArgList:  ArgList ',' Arg
| Arg
;
    Arg:    Type ID
;
    CompoundStmt:   '{' StmtList '}'
;
    StmtList:   StmtList Stmt
|
;
    Stmt:   WhileStmt
| Declaration
| ForStmt
| IfStmt
| PrintFunc
| ';'
;

    /* Type Identifier block */
    Type:   INT 
| FLOAT
| CHAR
| DOUBLE
| VOID 
;

    /* Loop Blocks */ 
    WhileStmt: WHILE '(' Expr ')' Stmt  
| WHILE '(' Expr ')' CompoundStmt 
;

    /* For Block */
   ForStmt: FOR '(' Expr ';' Expr ';' Expr ')' Stmt 
   | FOR '(' Expr ';' Expr ';' Expr ')' CompoundStmt 
   | FOR '(' Expr ')' Stmt 
   | FOR '(' Expr ')' CompoundStmt 
;

   /* IfStmt Block */
    IfStmt : IF '(' Expr ')' 
    Stmt 
;

    /* Struct Statement */
    StructStmt : STRUCT ID '{' Type Assignment '}'  
;

     /* Print Function */
     PrintFunc : PRINTF '(' Expr ')' ';'
;

    /*Expression Block*/
    Expr:   
| Expr LE Expr 
| Expr GE Expr
| Expr NE Expr
| Expr EQ Expr
| Expr GT Expr
| Expr LT Expr
| Assignment
| ArrayUsage
;
    %%

    int count=0;
    #include"lex.yy.c"
    #include<ctype.h>
    int main(int argc, char *argv[])
    { 
yyin=fopen(argv[1], "r");

     if(!yyparse())
    printf("\nParsing complete\n");
else
    printf("\nParsing failed\n");

fclose(yyin);
   return 0;
   }

   yyerror(char *s) {
printf("%d : %s %s\n", line, s, yytext );
   }

C文件(add.c)

   #include <stdio.h>
   int main()
   {
   int c;
   int a=10;
   int b=10; 
   c=a+b;
   printf("the value of c is %d",c);
   return 0;
   }  

编译步骤如下:

    $ lex c.l
$ yacc c.y
$ gcc y.tab.c -ll -ly 
$ ./a.out add.c

输出结果为:

       8 : syntax error "
       Parsing complete

所以问题为什么在代码中出现这个问题?要对代码进行任何更改以使其正常工作。我不知道问题出在哪里所以我发布了整个lex和yacc代码...任何建议会有所帮助..谢谢提前..

1 个答案:

答案 0 :(得分:1)

#include的lex模式需要一个C源文件中没有的尾随空格。