【问题标题】:Grammar for Linux command line with yacc and lex带有 yacc 和 lex 的 Linux 命令行语法
【发布时间】:2013-05-02 06:47:06
【问题描述】:

我想写一个正式的语法来描述一些 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 文件??

【问题讨论】:

  • 这可能不可行,因为 shell 语言对上下文非常敏感。
  • 请注意,空格(尤其是换行符)在命令行中很重要,因此您不能像在许多不重要的语言中那样在正式语法中忽略它。

标签: linux ubuntu grammar yacc lex


【解决方案1】:

我无法理解您的语法,但这里有一个基本的简化版本可以帮助您入门。

注意:返回的字符串是 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

使用 bison 构建它:

cl.l 中的#include "y.tab.h" 更改为#include "cl.tab.h"

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

【讨论】:

  • @parkhydr:你能帮帮我吗?
  • 我在 ubuntu 上使用 flex 和 yacc。我用迷你 C 编译器对它们进行了测试,它们运行良好。
猜你喜欢
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 2016-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多