2013-05-02 57 views
1

我想寫一個正式的語法來描述一些GNU/Linux工具的命令行用法。用於Linux命令行的語法與yacc和lex

首先,我想定義語法:

Start -> COMMAND AXIS 

AXIS -> EMPTY | INTER 

INTER -> VALUE | -OPT 

VALUE -> any characters for files 

OPT -> OPION AXIS 

OPTION -> WORD 

WORD -> out | in | ... | LETTERS 

LETTERS -> aLETTER |bLETTER | ... | zLETTER 

LETTER -> a| b | c | ... | EMPTY | LETTERS 

EMPTY -> 

COMMAND -> ls | tar | touch | openssl | vi | ... | cat 

我將使用這個語法用lex和yacc解析命令。我該如何定義.l & .c文件?

+0

它可能不是可行的,因爲shell語言是相當上下文敏感的。 – 2013-05-02 06:57:07

+0

請注意,命令行中的空格(特別是換行符)非常重要,因此您不能在正式語法中忽略它,因爲您可以在很多語言中忽略它。 – 2013-05-02 19:27:13

回答

2

我遇到了語法問題,但這裏有一個基本的簡化版本來幫助你入門。

注意:返回的字符串是strdup()ed。它們應該在使用後真正釋放。

這裏的cl.l

%{ 
#define YYSTYPE char* 
#include "y.tab.h" 
%} 

%% 

ls|tar|touch|openssl|vi|cat  { yylval = strdup(yytext); return COMMAND; } 

[A-Za-z0-9]+ { yylval = strdup(yytext); return VALUE; } 

-[A-Za-z0-9]+ { yylval = strdup(yytext); return OPTION; } 

[ \t] /* ignore whitespace */ ; 

\n { return EOL; } 

%% 

和這裏的cl.y

%{ 
#include <stdio.h> 
#include <string.h> 
#define YYSTYPE char * 
%} 

%token COMMAND VALUE OPTION EOL 
%% 

start: command EOL { return 0; } 

command: COMMAND axis {printf("Command %s\n", $1);} 
     | COMMAND {printf("Command %s\n", $1);} 

axis: inter | axis inter ; 

inter: VALUE {printf("Inter value %s\n", $1);} 
     | OPTION {printf("Inter option %s\n", $1);} 
%% 
int main (void) { 
    return yyparse(); 
} 

int yyerror (char *msg) { 
    return fprintf (stderr, "Error: %s\n", msg); 
} 

要使用的yacc構建它:

flex cl.l 
yacc -d cl.y 
gcc -o cl y.tab.c lex.yy.c -lfl 

要使用野牛建立它更改#include "y.tab.h"#include "cl.tab.h"cl.l

flex cl.l 
bison -d cl.y 
gcc -o cl cl.tab.c lex.yy.c -lfl 
+0

我使用flex和yacc .. – alibenmessaoud 2013-05-02 18:46:34

+0

@parkhydr:你能幫我嗎? – alibenmessaoud 2013-05-02 19:41:53

+1

我在ubuntu上使用flex和yacc。我測試了它們的迷你C編譯器,它們工作正常。 – alibenmessaoud 2013-05-02 19:42:56