Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / legion / src / parser / lexer.l
/*
* ========== Copyright Header Begin ==========================================
*
* OpenSPARC T2 Processor File: lexer.l
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
*
* The above named program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
*
* The above named program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ========== Copyright Header End ============================================
*/
%{
/* any C includes here */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include "basics.h"
#include "allocate.h"
#include "lexer.h"
#include "simcore.h"
#include "config.h"
#include "fatal.h"
lexer_t lex; /* additional return value info */
#if TESTRIG /* { */
#include <stdarg.h>
#include <errno.h>
void fatal(char *s,...);
#endif /* } */
%}
DECNUM ("0"|([1-9][0-9]*))
%x comment
%x string
%%
<<EOF>> return T_EOF;
"{" return T_L_Brace;
"}" return T_R_Brace;
";" return T_S_Colon;
"+" return T_Plus;
"-" return T_Minus;
"," return T_Comma;
"@" return T_Amp;
^"#"[ \t].*$ {
char lbuf[1024];
int num;
if (sscanf(lextext,"# %d \"%[^\"]\"", &num, lbuf)!=2)
lex_fatal("Illegal # directive");
lex.linenum = num-1;
if (lex.fnamep != (char*)0) Xfree(lex.fnamep);
lex.fnamep = Xstrdup(lbuf);
}
\" BEGIN(string);
<string>\" BEGIN(INITIAL);
<string>([^"\n]|(\\\"))* {
lex.strp = lextext;
return T_String;
}
<string>\n {
lex_fatal("unterminated string");
}
"0x"[0-9A-F][0-9A-F]* {
lex.strp = lextext;
lex.val = strtoull(lextext, (char **)NULL, 16);
return T_Number;
}
"0x"[0-9a-f][0-9a-f]* {
lex.strp = lextext;
lex.val = strtoull(lextext, (char **)NULL, 16);
return T_Number;
}
{DECNUM} {
lex.strp = lextext;
lex.val = atoll(lextext);
return T_Number;
}
[0-9a-f][0-9a-f]* {
lex.strp = lextext;
lex.val = strtoull(lextext, (char **)NULL, 16);
return T_HexString;
}
[0-9A-F][0-9A-F]* {
lex.strp = lextext;
lex.val = strtoull(lextext, (char **)NULL, 16);
return T_HexString;
}
{DECNUM}[KkMmGg] {
char * ep;
lex.val = strtoull(lextext, &ep, 10);
switch(*ep) {
case 'G': case 'g':
lex.val <<= 30;
break;
case 'M': case 'm':
lex.val <<= 20;
break;
case 'K': case 'k':
lex.val <<= 10;
break;
default:
lex_fatal("parsing number");
}
lex.strp = lextext;
return T_Number;
}
[A-Za-z_][A-Za-z_0-9]* {
lex.strp = lextext;
return T_Token;
}
/* Note: . = any character EXCEPT newline */
\/\/ {
lex.strp = lextext;
return T_String;
}
[\t ]* { /* nada - swallow white space */ }
"\n" {
lex.linenum ++;
}
. {
lex_fatal("Illegal character %s", lextext);
}
%%
void init_lexer(char * fnamep, FILE *fp, char * cleanup_filep)
{
lex.cleanup_filep = cleanup_filep ? Xstrdup(cleanup_filep) : (char*)0;
lex.linenum = 1;
lex.fnamep = Xstrdup(fnamep);
lex.ungot_available = false;
lex.last_token = T_Error;
lexin = fp;
}
lexer_tok_t lex_get_token()
{
if (lex.ungot_available) {
lex.ungot_available = false;
return lex.last_token;
}
lex.last_token = lexlex();
return lex.last_token;
}
void lex_unget()
{
if (lex.ungot_available) fatal("Internal error, lex_unget with token already ungot");
lex.ungot_available = true;
}
void lex_get(lexer_tok_t expected)
{
lexer_tok_t tok;
char *s;
char buffer[1024];
tok = lex_get_token();
if (tok == expected) return;
switch(tok) {
case T_EOF: s="end of file"; break;
case T_L_Brace: s="{"; break;
case T_R_Brace: s="}"; break;
case T_S_Colon: s=";"; break;
case T_Plus: s="+"; break;
case T_Minus: s="-"; break;
case T_Number: s="number"; break;
case T_HexString: s="hex string"; break;
case T_String: s="string"; break;
case T_Token:
sprintf(buffer,"token %s", lex.strp);
s=buffer;
break;
case T_Error: s="error"; break;
default:
s="unknown token - internal error";
break;
}
lex_fatal("unexpected %s", s);
}
/*
* Special version of fatal for the lexer
* to enable cleanup of stuff before death
*/
void lex_fatal(char * fmt, ...)
{
va_list args;
if (errno!=0) perror("FATAL: "); else fprintf(stderr,"FATAL: ");
if (fmt) {
va_start(args, fmt);
(void)vfprintf(stderr, fmt, args);
va_end(args);
}
if (lex.cleanup_filep != (char *)0) {
unlink(lex.cleanup_filep);
Xfree(lex.cleanup_filep);
}
fprintf(stderr," at line %d of %s\n", lex.linenum, lex.fnamep);
Xfree(lex.fnamep);
SANITY( lex.fnamep = (char*)0; );
SANITY( lex.cleanup_filep = (char*)0; );
exit(1);
}
int lexwrap()
{
return 1;
}
#if TESTRIG /* { */
main()
{
lexer_tok_t tok;
lex.linenum = 1;
lex.fnamep = "test";
do {
tok = lexlex();
fprintf(stderr,"token = %d at line %d in %s\n",tok, lex.linenum, lex.fnamep);
} while (tok!=T_Error && tok!=T_EOF);
}
void fatal(char* fmt, ...)
{
va_list args;
int status;
if (errno!=0) perror("FATAL: "); else fprintf(stderr,"FATAL: ");
if (fmt) {
va_start(args, fmt);
(void)vfprintf(stderr, fmt, args);
va_end(args);
}
fprintf(stderr,"\n");
fflush(stderr);
fflush(stdout);
thr_exit(&status);
}
#endif /* } */