/* * ========== 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 #include #include #include #include #include #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 #include void fatal(char *s,...); #endif /* } */ %} DECNUM ("0"|([1-9][0-9]*)) %x comment %x string %% <> 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); \" BEGIN(INITIAL); ([^"\n]|(\\\"))* { lex.strp = lextext; return T_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 /* } */