2012-02-23 70 views
1

我使用Lex,Yacc和C++编写自定义shell。它正在Unix环境中运行。只要标记之间有空格,它目前工作正常。例如:Lex解析无空格

ls | grep test > out 

将通过:

WORD PIPE WORD WORD GREAT WORD 

到Yacc的,然后行动从那里取。但是,如果没有空格,我需要它来工作。例如:

ls|grep test>out 

应该和前面的命令一样工作。然而,它目前只通过:

WORD WORD 

有没有一种方法来解析输入之前,Lex标记它呢?

编辑:

这里是我的莱克斯文件:

%{ 

#include <string.h> 
#include "y.tab.h" 

%} 

%% 

\n { 
    return NEWLINE; 
} 

[ \t] { 
    /* Discard spaces and tabs */ 
    } 

">" { return GREAT; } 

">&" { return GREATAMPERSAND; } 

">>" { return GREATGREAT; } 

">>&" { return GREATGREATAMPERSAND; } 

"<" { return LESS; } 

"|" { return PIPE; } 

"&" { return AMPERSAND; } 

[^ \t\n][^ \t\n]* { 
    /* Assume that file names have only alpha chars */ 
    yylval.string_val = strdup(yytext); 
    return WORD; 
} 

. { 
    /* Invalid character in input */ 
    return NOTOKEN; 
} 

%% 
+0

你需要证明你的lex文件,以便我们能够帮助您。您必须在某处错误定义了令牌才能获得此行为。 – Dervall 2012-02-23 14:41:45

回答

0

我想通了。 WORD包括管道和其他特殊字符。 我改成了

[^\|\>\<\& \t\n][^\|\>\<\& \t\n]* { 
    yylval.string_val = strdup(yytext); 
    return WORD; 
} 

,现在它的工作原理。

1

你需要改变你的一个WORD的定义。现在,当它遇到字母字符时,它会将所有内容都视为WORD的一部分。

你想改变这种状况,因此不包括任何标点符号,你正在使用用于其他用途:

[^ \t\n\>\<\|\&]+ { 
    /* Assume that file names have only alpha chars */ 
    yylval.string_val = strdup(yytext); 
    return WORD; 
}