Suppose I want my Lex and Yacc program to parse the command line arguments like:
./a.out 开发者_开发百科show memory
I want lex to parse the string "show memory". How do I accomplish this?
You'll need to concatenate all the arguments into a big string, by inserting whitespace between them. Then feed the remaining text buffer to Lex/Yacc, by re-defining the YY_INPUT
macro so it reads input from your text buffer.
The start could be something like:
#include <stdio.h>
#include <string.h>
char *argbuf;
size_t arglen;
int main(int argc, char *argv[])
{
int i;
// Compute total length of all arguments, with a single space between.
arglen = 0;
for(i = 1; argv[i] != NULL; i++)
arglen += 1 + strlen(argv[i]);
// Allocate buffer space.
argbuf = malloc(arglen);
if(argbuf == NULL)
{
fprintf(stderr, "No memory for argument buffer, aborting");
exit(1);
}
// Concatenate all arguments. This is inefficient, but simple.
argbuf[0] = 0;
for(i = 1; argv[i] != NULL; i++)
{
if(i > 1)
strcat(argbuf, " ");
strcat(argbuf, argv);
}
// Here we should be ready to call yyparse(), if we had implemented YY_INPUT().
return 0;
}
int main(int argc, char **argv) {
if(argc > 1) {
if(argv[1])
yy_scan_string(argv[1]);
}
yyparse();
return 0;
}
What's wrong with doing it the old fashioned way?:
if(argc > 1 && !strcmp(argv[1],"show"))
{
if(argc > 2)
{
if(!strcmp(argv[2],"memory"))
...
else if(!strcmp(argv[2],"cpu"))
...
else ...
}
}
Besides, getopt()
and friends are more appropriate.
My blog article Parsing command line parameters with Yacc & Flex explains this with a working example. There is no need to concatenate the argument string. The reason is given in the article.
The blurb is:
Every once in a while someone comes along and asks how to parse command line parameters with Yacc & Flex. This is rather straight forward, but requires some knowledge of the generated code to get right.
Here we present a source template that does this. The user only has to edit the grammar and scanning rules. Some knowledge of C, Yacc and Flex is assumed.
The code is WTFPL licensed
The template is written for Berkeley Yacc and the reflex variant of Flex. It may be made to work with GNU Bison and SourceForge Flex, possibly with a few changes.
What you get is a template where you can just insert your lexical and grammar specification.
Please ask questions about the using and adapting the template itself to the blog comments.
精彩评论