سؤال

I recently download a opensource project named re1(Goggle) because my current research topic is about regular expression matching with nfa and dfa. re1 is a very very simple and small project, but there is a parse.y file but I never met. After google, I know it is generated by yacc(yet another compiler compiler). There is also a makefile so I can run it in Linux, but now I want to run it in Visual Studio(Windows) because I need to debug step by step(F5, F10, F11,etc. are very userful).But now it cannot build in VS because the .y file that VS cannot recognize it, there are many "error LNK2019: unresolved external symbol". I do not know how to settle it, can I convert or restore it to .c file? How to do it?

following is part of parse.y:

%{
#include "regexp.h"

static int yylex(void);
static void yyerror(char*);
static Regexp *parsed_regexp;
static int nparen;

%}

%union {
    Regexp *re;
    int c;
    int nparen;
}

%token  <c> CHAR EOL
%type   <re>    alt concat repeat single line
%type   <nparen> count

%%

line: alt EOL
    {
        parsed_regexp = $1;
        return 1;
    }

alt:
    concat
|   alt '|' concat
    {
        $$ = reg(Alt, $1, $3);
    }
;

concat:
    repeat
|   concat repeat
    {
        $$ = reg(Cat, $1, $2);
    }
;

repeat:
    single
|   single '*'
    {
        $$ = reg(Star, $1, nil);
    }
|   single '*' '?'
    {
        $$ = reg(Star, $1, nil);
        $$->n = 1;
    }
|   single '+'
    {
        $$ = reg(Plus, $1, nil);
    }
|   single '+' '?'
    {
        $$ = reg(Plus, $1, nil);
        $$->n = 1;
    }
|   single '?'
    {
        $$ = reg(Quest, $1, nil);
    }
|   single '?' '?'
    {
        $$ = reg(Quest, $1, nil);
        $$->n = 1;
    }
;

count:
    {
        $$ = ++nparen;
    }
;

single:
    '(' count alt ')'
    {
        $$ = reg(Paren, $3, nil);
        $$->n = $2;
    }
|   '(' '?' ':' alt ')'
    {
        $$ = $4;
    }
|   CHAR
    {
        $$ = reg(Lit, nil, nil);
        $$->ch = $1;
    }
|   '.'
    {
        $$ = reg(Dot, nil, nil);
    }
;

%%

static char *input;
static Regexp *parsed_regexp;
static int nparen;
int gen;

static int
yylex(void)
{
    int c;

    if(input == NULL || *input == 0)
        return EOL;
    c = *input++;
    if(strchr("|*+?():.", c))
        return c;
    yylval.c = c;
    return CHAR;
}

void
fatal(char *fmt, ...)
{
    va_list arg;

    va_start(arg, fmt);
    fprintf(stderr, "fatal error: ");
    vfprintf(stderr, fmt, arg);
    fprintf(stderr, "\n");
    va_end(arg);
    exit(2);
}

static void
yyerror(char *s)
{
    fatal("%s", s);
}


Regexp*
parse(char *s)
{
    Regexp *r, *dotstar;

    input = s;
    parsed_regexp = nil;
    nparen = 0;
    if(yyparse() != 1)
        yyerror("did not parse");
    if(parsed_regexp == nil)
        yyerror("parser nil");

    r = reg(Paren, parsed_regexp, nil); // $0 parens
    dotstar = reg(Star, reg(Dot, nil, nil), nil);
    dotstar->n = 1; // non-greedy
    return reg(Cat, dotstar, r);
}

I try to remove these symbols like %, token and type, but I do not know how to resolve the rule(%%), of course it doesn't work, how can I do in VS, does VS support yacc?

هل كانت مفيدة؟

المحلول

There are two tools that go hand in hand together.

Flex and Bison, the GNU team to "Lex and Yacc".

There's a great book called "Flex and Bison" and another called "Lex and Yacc" they are really worth reading, you can pick them up second hand for a few pennies.

Flex and Bison are two of the most under-appreciated things I know of. Constantly re-implemented.

Knowing about work that has already happens is very important. Do not try and read the output of Flex though, that is an optimised result created by a program and is not for human consumption! Instead read Flex's source-code when you know what it does.

the GPL license gives you a right to read it's source code. Enjoy it :)

BTW Unix stuff, the unix philosophy, tells us to write programs that write other programs for us, talk in human-readable text and do one job and one job only, but do it very well.

Flex and Bison are prime examples of this.

Another famous Raymond quote: "Prepare for the future, for it'll be here sooner than you think", both are still here and still very good.

نصائح أخرى

Instead of Yacc, look for Bison, which is the GNU free implementation of the old Yacc program. The parse.y file is not generated by Yacc/Bison, but it is its input file.

Some Unix and Unix-like systems, such as some Linux distributions, come with Bison already installed. On Windows, you have to download and install them separately. You can download and then install Bison for Windows.

Then run Bison with the .y file as input. It generates a C file, which you can then compile in Visual Studio.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top