%option noyywrap bison-bridge bison-locations
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TAG_STRING 1
#define TAG_NUMBER 2
#define TAG_IDENT 3
char *tag_names[] =
{
"END_OF_PROGRAM", "STRING", "NUMBER", "IDENT"
};
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;
float num;
char *st2;
};
typedef union Token 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);
}
%}
SPACE [\n\t ]+
STRING \'([^']|\'{2})+\'
DIGIT (\-)?[0-9]+(\.[0-9]+)?
IDENT [a-zA-Z]([a-zA-Z]*(\.)*[0-9]*)+
%x STRINGG STRINGG_IN
%%
{SPACE}
{DIGIT} {
yylval->num = atof(yytext);
return TAG_NUMBER;
}
{IDENT} {
yylval->ident = yytext;
return TAG_IDENT;
}
\' {BEGIN(STRINGG); continued = 1;yylval->st2 = (char*) malloc (1000);}
<STRINGG>\\\n err ("unexpected \n, expected ' ");
<STRINGG>[^']* {
continued = 1;
yylval->st2 = strcat (yylval->st2, yytext);
}
<STRINGG>\'\' {
continued = 1;
yylval->st2 = strcat (yylval->st2, yytext);
}
<STRINGG>\' {
yylval->st2 = strcat (yylval->st2, yytext);
BEGIN(0);
return TAG_STRING;
}
<STRINGG><<EOF>> {
err("end of program found, ' expected");
return 0;
}
. err("unexpected character");
%%
#define PROGRAM "'sfg''df' % dg435..2 -1.3"
int main ()
{
int tag;
YYSTYPE value;
YYLTYPE coords;
init_scanner (PROGRAM);
do
{
tag = yylex (&value ,&coords);
if (tag != 0)
{
print_frag(&coords);
if (tag == 1) {
printf(" %s \'%s\n", tag_names[tag], value.st2);
free (value.st2);
} else {
if (tag == 2 ) {
printf(" %s %f\n", tag_names[tag], value.num);
} else {
printf(" %s %s\n", tag_names[tag], value.ident);
}
}
}
}
while ( tag != 0);
return 0;
}