2016-10-01 3 views
0

У меня есть проект в моем университете, чтобы сделать мини-оболочку с языком C. Для синтаксического анализа командной строки я использую инструменты: lex и yacc. Но я хочу разобрать линию. Когда токен обнаружен, добавьте аргумент в мою команду struct и когда я нахожу вывод yyparse для новой строки для команды execute. После печати строки и relauch разобрать ... Мой закон файл:Как выйти из функции yyparse после новой строки?

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); 
    } 

Спасибо за вашу помощь.

ответ

0
cmd_lists: cmd_lists command | ; 

Это, как представляется, символ терминала, хотя они обычно помещаются сверху, а не внизу. В любом случае, эта грамматика говорит, что cmd_list может содержать ноль или более command элементов, поэтому парсер ведет себя правильно, готовясь принять другой.

Если вы этого не хотите, удалите cmd_list продукции.

+0

Благодарим за помощь. Я удаляю строку cmd_list (cmd_lists: cmd_lists command |;), и я заменю% start cmd_list на команду% start. Но когда я набираю «exit» или просто newline, ничего не происходит. Я добавил printf в действии, ничего не отображается. – Oneill

Смежные вопросы