野牛不会返回正确的令牌

时间:2019-10-11 02:42:11

标签: parsing bison flex-lexer

我正在建立一个语法,我需要解析lambda x : x + x end,提取args = "x"body = "x + x"。我的语法正确返回了body,但是argx : x + x end。 arg应该停在冒号上,但不要停。

这是我的语法:

%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *oper(char op, char *l, char *r) {
    char *res = malloc(strlen(l)+strlen(r)+6);
    sprintf(res, "(%c %s %s)", op, l, r);
    return res;
}

char *dup(char *orig) {
    char *res = malloc(strlen(orig)+1);
    strcpy(res,orig);
    return res;
}

char* lambda(char *arg, char *body){
    printf("arg:   %s\nbody:  %s\n\n", arg, body);
    char *res = malloc(strlen(arg) + strlen(body) + 10);

    sprintf(res,"(func %s (%s))", arg, body);

    return res;
}

int yylex();
void yyerror(char *);
%}

%union {
    char *val;
}

%token  <val> NUM
%token  <val> SYMBOL
%token  LAMBDA
%token  COLON
%token  END
%type   <val> exp

%left ADD

/* Gramatic */
%%

input:
    |    exp     { puts($1); }
    |    error   { fprintf(stderr, "Invalid input\n"); }
;

exp:
         NUM                         { $$ = dup($1); }
    |    SYMBOL                      { $$ = dup($1); }
    |    LAMBDA SYMBOL COLON exp END { $$ = lambda($2, $4); }
    |    exp ADD exp                 { $$ = oper('+', $1, $3); }
;

%%

void yyerror(char *s) {
  fprintf(stderr,"%s\n",s);
}

lex文件非常简单:

alpha   [A-Za-z]
dig     [0-9]
name    {alpha}({alpha}|{dig})*
number  [-+]?{dig}+\.?([eE][-+]?{dig}+)?

%{
#include <math.h>
#include "parser.tab.h"

%}


%%
{number}    { yylval.val = yytext; return NUM; }

[ \t\n]+   /* whitespace */

[+]        { return ADD; }
(end)      { return END; }
(:)        { return COLON; }
(lambda)   { return LAMBDA; }

{name}    { yylval.val = yytext; return SYMBOL; }

.    {  fprintf(stderr, "Entrada ignorada\n-->%s\n", yytext); }

%%

/* Local Variables: */
/* mode: c */
/* End: */

然后我用Makefile进行编译:

parser: parser.tab.o lex.yy.o main.o
    gcc -o $@ $^  -lfl

parser.tab.o: parser.y
    bison -d parser.y
    gcc -c parser.tab.c

lex.yy.o: parser.l
    flex parser.l
    gcc -c lex.yy.c

然后,运行一个简单的测试,我得到了错误的结果:

$ echo "lambda x : x + x end" | ./parser
arg:   x : x + x end
body:  (+ x x)

(func x : x + x end ((+ x x)))

任何指导表示赞赏:)

0 个答案:

没有答案