[prog] lex and yacc

Jimen Ching jching at flex.com
Thu Jan 22 23:20:17 EST 2004


On Fri, 23 Jan 2004, Sue Stones wrote:
>statements include:
>	incr name;
>	decr name;
>	while name <> 0 do;
>		.
>		.
>	end;
>
>Brookshear then allowe the language to be extended by
>	clear name;
>	name1 <- name2

I don't know how far you've gotten.  For me, when I first learned
lex/yacc, it helped a lot to read someone else's source files and build
from that.  With that, I'm including some source files for your language
described above.  I didn't implement the full language.  But there's
enough to easily add more.  Note, there are a lot more to lex/yacc than my
example.  But it's a starting point.

To compile the code, execute the following commands:

	bison -d tst.y
	flex tst.l
	gcc lex..yy.c tst.tab.c -o tst
	./tst tst.in

Note the order of the bison/flex commands.  The order is important,
because bison is asked to generate a header file with the token macros
that are used by tst.l.

Let me know if you need help extending this example with the other
language statements.

--jc
-- 
Jimen Ching (WH6BRR)      jching at flex.com     wh6brr at uhm.ampr.org


-------------------- tst.l -----------------
%{

/* Include token definitions from yacc output. */
#include "tst.tab.h"

%}

/* Regular expressions that we need. */

NL						[\n]
WS						[ \t\r\b]
WSs						{WS}+
LetterU					[a-zA-Z_]
WordNumU				[0-9a-zA-Z_]
Word					{LetterU}{WordNumU}*

%%

	/* Token definition (comment must not start on first column). */

{NL} { }
{WSs} { }
incr { return YYINCR; }
decr { return YYDECR; }
{Word} { yylval.simple_string = yytext; return YYNAME; }
. { return yytext[0]; }

%%

int
yywrap(void)
	{
	/* If supporting multiple files, update yyin here. */
	return 1;
	}

--------------------------------------------

------------------- tst.y -------------------
%{

/* Header inclusion and variable declarations. */

#include <stdio.h>

extern FILE *yyin; /* Input for yacc parser. */
#ifdef YYTEXT_POINTER
extern char *yytext; /* Current symbol for error reporting. */
#else
extern char yytext[];
#endif
extern void yyerror(char *str); /* Our version. */
extern int yywrap(void); /* Our version. */
extern int yylex(void); /* Lexical analyzer function. */
extern int yyparse(void); /* Parser function. */

 %}

/* Types and variables for rules. */

%union
	{
	char *simple_string;
	};

%token YYINCR
%token YYDECR
%token <simple_string> YYNAME

%type <simple_string> name

%%

source_text:
		statement_list
	;

statement_list:
		statement
	|	statement_list statement
	;

statement:
		YYINCR name ';'
		{
			printf("parsed statement: incr %s\n", $2);
		}
	|	YYDECR name ';'
		{
			printf("parsed statement: decr %s\n", $2);
		}
	;

name:
		YYNAME
		{
			$$ = $1;
		}
	;

%%

void
yyerror(char *str)
	{
	printf("error: %s\n", str);
	}

int
main(int argc, char *argv[])
	{
	if (argc > 1)
		{
		yyin = fopen(argv[1], "r");
		yyparse(); /* Calls yylex() for tokens. */
		}
	else
		printf("syntax: %s filename\n", argv[0]);
	return 0;
	}

--------------------------------------------

-------------------- tst.in -----------------
incr var1;
decr var2;
--------------------------------------------


More information about the Programming mailing list