%option noyywrap bison-bridge bison-locations
%{
#include < stdio .h >
#include < stdlib .h >
#define TAG_IDENT 1
#define TAG_NUMBER 2
#define TAG_CHAR 3
#define TAG_LPAREN 4
#define TAG_RPAREN 5
#define TAG_PLUS 6
#define TAG_MINUS 7
#define TAG_MULTIPLY 8
#define TAG_DIVIDE 9
char *tag_names[] =
{
"END_OF_PROGRAM" , "IDENT" , "NUMBER" ,
"CHAR" , "LPAREN" , "RPAREN" , "PLUS" ,
"MINUS" , "MULTIPLY" , "DIVIDE"
};
struct Position
{
int line , pos , index;
};
void print_pos ( struct Position *p )
{
printf("(%d,%d)" ,p->line, p->pos);
}
struct Fragment
{
struct Position starting, following;
};
typedef struct Fragment YYLTYPE;
void print_frag ( struct Fragment *f )
{
print_pos (&(f->starting));
printf ("-");
print_pos(&(f->following));
}
union Token {
char *ident;
long num;
char ch;
};
typedef union Tokens YYSTYPE;
int continued;
struct Position cur;
#define YY_USER_ACTION\
{\
int i;\
if (! continued)\
yylloc->starting = cur;\
continued = 0;\
for (i = 0; i < yyleng; i++)\
{\
if (yytext[i] == ’\n’)\
{\
cur.line++;\
cur.pos = 1;\
}\
else\
cur.pos++;\
cur.index++;\
}\
yylloc->following = cur;\
}
void init_scanner(char *program)
{
continued =0;
cur.line = 1;
cur.pos =1;
cur.index = 0;
yy_scan_string(program);
}
void err(char *msg)
{
printf("Error ");
print_pos(&cur);
printf(": %s\n",msg);
}
%}
LETTER [a-zA-Z]
DIGIT [0-9]
IDENT {LETTER}({LETTER}|{DIGIT})*
NUMBER {DIGIT}+
%x COMMENTS CHAR_1 CHAR_2
%%
[\n\t ]+
\/\* BEGIN(COMMENTS); continued =1;
<COMMENTS>[~*]* continued =1;
<COMMENTS>\*\/ {
print_frag(yylloc);
printf(" comment\n");
BEGIN(0);
}
<COMMENTS>\* continued =1;
<COMMENTS><<EOF>> {
err("end of program found, '*/' expected");
return 0;
}
\( return TAG_LPAREN;
\) return TAG_RPAREN;
\+ return TAG_PLUS;
- return TAG_MINUS;
\* return TAG_MULTIPLY;
\/ return TAG_DIVIDE;
{IDENT} {
yylval - > ident = yytext;
return TAG_IDENT;
}
{NUMBER} {
yylval - > num = atoi ( yytext );
return TAG_NUMBER ;
\’
}
\’ BEGIN(CHAR_1); continued =1;
. err("unexpected char");
<CHAR_1,CHAR_2>\n {
err("newline in constant");
BEGIN(0);
yylval -> ch =0;
return TAG_CHAR;
}
<CHAR_1>\\n yylval -> ch = '\n'; BEGIN(CHAR_2); continued =1;
<CHAR_1>\\\’ yylval -> ch = '\n'; BEGIN(CHAR_2); continued =1;
<CHAR_1>\\\\ yylval -> ch = '\n'; BEGIN(CHAR_2); continued =1;
<CHAR_1>\\. {
err("unknown error");
yylval -> ch =0;
BEGIN(CHAR_2);
continued =1;
}
<CHAR_1>\’ {
err("empty");
BEGIN(0);
yylval->ch =0;
return TAG_CHAR;
}
<CHAR_1>. yylval -> = yytext[0]; BEGIN(CHAR_2); continued =1;
<CHAR_2>\’ BEGIN(0); return TAG_CHAR;
<CHAR_2>[^\n\’]* err("to many chars"); continued =1;
%%
#define PROGRAM "/* Expression */ ( alpha + ’ beta ’ - ’\\n ’)\ n " \
" * 666666666 /* blah - blah - blah "
int main ()
{
int tag;
YYSTYPE value;
YYLTYPE coords;
init_scanner (PROGRAM);
do
{
tag = yylex (&value ,&coords);
if (tag != 0)
{ ... }
}
while ( tag != 0);
return 0;
}