我想写一个正式的语法来描述一些GNU / Linux工具的命令行用法。
首先,我想定义一个语法:
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 :(得分: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