如何在换行后退出yyparse函数?

时间:2016-10-01 06:54:09

标签: c bison yacc

我的大学里有一个用C语言编写迷你shell的项目。要解析命令行,我使用工具:lex和yacc。但我想解析这条线。当检测到令牌时,在我的struct命令中添加参数,当我找到换行符退出yyparse for execute command时。打印提示后,再打开解析... 我的lex文件:

Chiffre [0-9]
Lettre [a-zA-Z]
Alphanum ({Chiffre}{Lettre})+

%{

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "parser.tab.h"

%}
%%
[ \t]+ {}
"\n" {
   return '\n';
}
"||" {
 return OR;
}
"|" {
  return PIPE;
}
"&&" {
  return AND;
 }
"&" {
  return AMPERSAND;
}

"2>" {
  return ERR_GREAT;
}

">&" {
  return GREAT_AMP;
}

"2>>" {
 return ERR_GREAT_GREAT;
}
">>&" {
  return GREAT_GREAT_AMP;
}
">>" {
 return GREAT_GREAT;
}

">" {
 return GREAT;
}

"<" {
  return LESS;
}

";" {
  return SEMICOLON;
}

"exit" {
   return EXIT;
}

({Lettre}_){1}({Alphanum}_) {
    return IDENTIFIER;
}
[^ \t|><&\;][^ \t|><&\;]* {
 return WORD;
}
%%
 int yywrap(void){return 1;}

我尝试使用YYACCEPT退出yyparse但是没有工作。 yacc文件:

%{
#include <stdio.h>
void yyerror(const char *s);
extern int yylex();
extern char* yytext;
%}
%token PIPE AND OR AMPERSAND BLANK WORD IDENTIFIER GREAT GREAT_GREAT LESS ERR_GREAT ERR_GREAT_GREAT GREAT_AMP GREAT_GREAT_AMP SEMICOLON EXIT
%start cmd_lists
%union { char str[256]; int val; }
%error-verbose
%% 
list_arg: list_arg WORD | /*empty*/;
cmd_args: WORD list_arg io_list;
pipeline: pipeline PIPE cmd_args | pipeline SEMICOLON cmd_args | pipeline AND cmd_args | pipeline OR cmd_args | cmd_args ;
io: GREAT WORD | GREAT_GREAT WORD | LESS WORD | ERR_GREAT WORD | ERR_GREAT_GREAT WORD | GREAT_AMP WORD | GREAT_GREAT_AMP WORD;
io_list: io_list io | /*empty*/ ;
background: AMPERSAND | /*empty*/ ;
command: pipeline background '\n'{
        printf("cmd newline\n");
        YYACCEPT;
      }
     |'\n'{
        printf("newline\n");
       YYACCEPT;
     }
     |EXIT '\n'{
       printf("exit newline\n");
       YYACCEPT;
     }
     ;

   cmd_lists: cmd_lists command | ;
   %%

   void yyerror(const char *s){
       fprintf(stderr,"yyerror : erreur : %s.\n",s);
   }

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

cmd_lists: cmd_lists command | ;

这似乎是终端符号,尽管它们通常位于顶部,而不是底部。无论如何,这个语法说cmd_list可以包含零个或多个command项,因此解析器通过准备接受另一个来正常运行。

如果您不想要,请删除cmd_list制作。