blob: 83f91ddfb8b4cdbe620d9df09a5447c0b75ac461 [file] [log] [blame]
Digit [0-9]
Literal [a-zA-Z_]
Hex [a-fA-F0-9]
Exp [Ee][+-]?{Digit}+
FS (f|F|l|L)
IS (u|U|l|L)+
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "util.h"
#include "tokens.h"
extern int opt_directives;
static void string(void);
static void comment(void);
static int directive(void);
static int yywrap(void) { return 1; }
%}
%%
"/*" { comment(); return COMMENT; }
"#" { return directive(); }
"auto" { return KEYWORD; }
"break" { return KEYWORD; }
"case" { return KEYWORD; }
"char" { return KEYWORD; }
"const" { return KEYWORD; }
"continue" { return KEYWORD; }
"default" { return KEYWORD; }
"do" { return KEYWORD; }
"double" { return KEYWORD; }
"else" { return KEYWORD; }
"enum" { return KEYWORD; }
"extern" { return KEYWORD; }
"float" { return KEYWORD; }
"for" { return KEYWORD; }
"goto" { return KEYWORD; }
"if" { return KEYWORD; }
"int" { return KEYWORD; }
"long" { return KEYWORD; }
"register" { return KEYWORD; }
"return" { return KEYWORD; }
"short" { return KEYWORD; }
"signed" { return KEYWORD; }
"sizeof" { return KEYWORD; }
"static" { return KEYWORD; }
"struct" { return KEYWORD; }
"switch" { return KEYWORD; }
"typedef" { return KEYWORD; }
"union" { return KEYWORD; }
"unsigned" { return KEYWORD; }
"void" { return KEYWORD; }
"volatile" { return KEYWORD; }
"while" { return KEYWORD; }
{Literal}({Literal}|{Digit})* { return IDENTIFIER; }
0[xX]{Hex}+{IS}? { return CONSTANT; }
0{Digit}+{IS}? { return CONSTANT; }
{Digit}+{IS} { return CONSTANT; }
{Digit}+ { return CONSTANT; }
'(\\.|[^\\'])+' { return CHARACTER; }
{Digit}+{Exp}{FS}? { return CONSTANT; }
{Digit}*"."{Digit}+({Exp})?{FS}? { return CONSTANT; }
{Digit}+"."{Digit}*({Exp})?{FS}? { return CONSTANT; }
"\"" { string(); return STRING; }
">>=" { return OPERATOR; }
"<<=" { return OPERATOR; }
"+=" { return OPERATOR; }
"-=" { return OPERATOR; }
"*=" { return OPERATOR; }
"/=" { return OPERATOR; }
"%=" { return OPERATOR; }
"&=" { return OPERATOR; }
"^=" { return OPERATOR; }
"|=" { return OPERATOR; }
">>" { return OPERATOR; }
"<<" { return OPERATOR; }
"++" { return OPERATOR; }
"--" { return OPERATOR; }
"->" { return OPERATOR; }
"&&" { return OPERATOR; }
"||" { return OPERATOR; }
"<=" { return OPERATOR; }
">=" { return OPERATOR; }
"==" { return OPERATOR; }
"!=" { return OPERATOR; }
"..." { return ELLIPSIS; }
";" { return ';'; }
"{" { return '{'; }
"}" { return '}'; }
"," { return ','; }
":" { return ':'; }
"=" { return '='; }
"(" { return '('; }
")" { return ')'; }
"[" { return '['; }
"]" { return ']'; }
"." { return '.'; }
"&" { return '&'; }
"!" { return '!'; }
"~" { return '~'; }
"-" { return '-'; }
"+" { return '+'; }
"*" { return '*'; }
"/" { return '/'; }
"%" { return '%'; }
"<" { return '<'; }
">" { return '>'; }
"^" { return '^'; }
"|" { return '|'; }
"?" { return '?'; }
[ \t\v\n\f] { return yytext[0]; }
. { return yytext[0]; }
%%
char *token_buffer;
static int maxtoken;
void
init_lex(void)
{
maxtoken = 40;
token_buffer = (char *)xmalloc(maxtoken + 1);
}
void
done_lex(void)
{
free(token_buffer);
}
static char *
extend_token_buffer(char *p)
{
int offset = p - token_buffer;
maxtoken = maxtoken * 2 + 10;
token_buffer = (char *)xrealloc(token_buffer, maxtoken + 2);
return token_buffer + offset;
}
static void
string(void)
{
char *p;
int c;
p = token_buffer;
*p++ = '"';
while ((c = input()) != EOF && c != '"') {
if (p >= token_buffer + maxtoken)
p = extend_token_buffer(p);
*p++ = c;
if (c == '\\')
*p++ = input();
}
if (c == EOF)
errx(1, "unexpected end of file in string");
*p++ = '"';
*p = '\0';
}
static void
comment(void)
{
char *p;
int c;
p = token_buffer;
*p++ = '/';
*p++ = '*';
while ((c = input()) != EOF) {
resync: if (p >= token_buffer + maxtoken)
p = extend_token_buffer(p);
*p++ = c;
if (c == '*')
if ((c = input()) == '/') {
*p++ = c;
*p = '\0';
return;
} else
goto resync;
}
*p = '\0';
}
static int
directive(void)
{
char *p;
int c;
if (opt_directives)
return '#';
p = token_buffer;
*p++ = '#';
while ((c = input()) != EOF && c != '\n') {
if (p >= token_buffer + maxtoken)
p = extend_token_buffer(p);
*p++ = c;
if (c == '\\')
*p++ = input();
}
*p++ = c;
*p = '\0';
return DIRECTIVE;
}