/* ** helper functions for Gerd Immeyer's grammar ** */ /**************************************************************************** * include files ***************************************************************************/ #include "nulldefs.h" extern "C" { #include #include #include #include #include } #include "common.hxx" #include "errors.hxx" #include "midlnode.hxx" #include "listhndl.hxx" #include "filehndl.hxx" #include "lextable.hxx" #include "lexutils.hxx" #include "grammar.h" #include "gramutil.hxx" #include "cmdana.hxx" #include "control.hxx" #include "textsub.hxx" extern "C" { #include "lex.h" } /**************************************************************************** * local definitions and macros ***************************************************************************/ #define warning(p) /* temp defintion to get rid of compiler probs */ #define NewCCGetch() (char) (pImportCntrl->GetChar()) #define NewCCputbackc(c) (char )(pImportCntrl->UnGetChar(c)) #define MAX_ID_LENGTH (31) #define MAX_DECIMAL_LENGTH (10) #define MAX_HEX_LENGTH (8) #define MAX_OCTAL_LENGTH (25) /*************************************************************************** * local data ***************************************************************************/ /*************************************************************************** * local procedures ***************************************************************************/ long convert(char *, short, short); token_t cnv_int(void); token_t cnv_hex(void); token_t cnv_octal(void); token_t cnv_float(void); token_t name(void); token_t map_token(token_t token); void lex_error(int number); /*************************************************************************** * global data ***************************************************************************/ // token_t TokenMap[LASTTOKEN]; short handle_import; short inside_rpc; lextype_t yylval; token_t toktyp_G; /* token type */ short toklen_G; /* len of token string */ char *tokptr_G; /* pointer to token string */ long curr_line_G; /* current line in file */ char *curr_file_G; /* current file name */ long tokval_G; /* value of constant token */ token_t latyp_G=NOTOKEN; /* lookahead holder */ short lalen_G; char *laptr_G; long laval_G; BOOL fAbandonNumberLengthLimits; /*************************************************************************** * external data ***************************************************************************/ extern short DebugLine; extern NFA_INFO *pImportCntrl; extern LexTable * pMidlLexTable; extern short CompileMode; extern SymTable * pBaseSymTbl; extern CMD_ARG * pCommand; extern ccontrol * pCompiler; extern char LastLexChar; /*************************************************************************** * external procedures ***************************************************************************/ token_t is_keyword( char *, short); /***************************************************************************/ token_t cnv_int(void) { token_t Tok = NUMERICCONSTANT; yylval.yy_numeric.pValStr = pMidlLexTable->LexInsert(tokptr_G); yylval.yy_numeric.Val = tokval_G = convert(tokptr_G, 10, MAX_DECIMAL_LENGTH ); LastLexChar = NewCCGetch(); if( (LastLexChar == 'L') || (LastLexChar == 'l')) { Tok = NUMERICLONGCONSTANT; } else { // LastLexChar = NewCCGetch(); if( (LastLexChar == 'U') || (LastLexChar == 'u')) { Tok = NUMERICULONGCONSTANT; if( ((LastLexChar = NewCCGetch()) != 'L') && (LastLexChar != 'l')) NewCCputbackc(LastLexChar); } else { NewCCputbackc( LastLexChar ); return NUMERICCONSTANT; } } return Tok; } token_t cnv_hex(void) { token_t Tok = HEXCONSTANT; unsigned long Val; yylval.yy_numeric.pValStr = pMidlLexTable->LexInsert(tokptr_G); tokptr_G += 2; /* skip 0x */ Val = yylval.yy_numeric.Val = tokval_G = convert(tokptr_G, 16, MAX_HEX_LENGTH); tokptr_G -= 2; LastLexChar = NewCCGetch(); if( (LastLexChar == 'L') || (LastLexChar == 'l')) { Tok = HEXLONGCONSTANT; } else { // LastLexChar = NewCCGetch(); if( (LastLexChar == 'U') || (LastLexChar == 'u')) { Tok = HEXULONGCONSTANT; if( ((LastLexChar = NewCCGetch()) != 'L') && (LastLexChar != 'l')) NewCCputbackc(LastLexChar); } else { NewCCputbackc(LastLexChar); return HEXCONSTANT; } } return Tok; } token_t cnv_octal(void) { token_t Tok = OCTALCONSTANT; unsigned long Val; yylval.yy_numeric.pValStr = pMidlLexTable->LexInsert(tokptr_G); Val = yylval.yy_numeric.Val = tokval_G = convert(tokptr_G, 8, MAX_OCTAL_LENGTH); LastLexChar = NewCCGetch(); if( (LastLexChar == 'L') || (LastLexChar == 'l')) { Tok = OCTALLONGCONSTANT; } else { // LastLexChar = NewCCGetch(); if( (LastLexChar == 'U') || (LastLexChar == 'u')) { Tok = OCTALULONGCONSTANT; if( ((LastLexChar = NewCCGetch()) != 'L') && (LastLexChar != 'l')) NewCCputbackc(LastLexChar); } else { NewCCputbackc(LastLexChar); return OCTALCONSTANT; } } return Tok; } token_t cnv_float(void) { warning("floating point constants not allowed"); yylval.yy_numeric.Val = tokval_G = 0; lex_error(101); yylval.yy_numeric.pValStr = pMidlLexTable->LexInsert(tokptr_G); return NUMERICCONSTANT; } long convert(char *ptr, short base, short MaxSize) { REG long answer = 0; REG char ch; BOOL fZeroIsNotALeadingZeroAnymore = FALSE; short count = 0; while ((ch = *ptr++) != 0) { if ((ch & 0x5f) >= 'A') answer = answer * base + (ch & 0x5f) - 'A'+ 10; else answer = answer * base + ch - '0'; if( ch == '0') { if( fZeroIsNotALeadingZeroAnymore ) count++; } else { fZeroIsNotALeadingZeroAnymore = TRUE; count++; } } if( ( count > MaxSize ) && !fAbandonNumberLengthLimits ) { ParseError( CONSTANT_TOO_BIG, (char *)NULL ); } return answer; } token_t name(void) { /* have received a name from the input file, first we */ /* check to see if it is a keyword. */ short InBracket = inside_rpc ? INBRACKET : 0; toktyp_G = is_keyword(tokptr_G, InBracket); return toktyp_G; } token_t map_token(token_t token) { static int lookahead_flag = false; if (lookahead_flag) return token; switch(token) { case IDENTIFIER: { if( strlen( tokptr_G ) > MAX_ID_LENGTH ) { ParseError( ID_TRUNCATED, tokptr_G ); // tokptr_G[ MAX_ID_LENGTH ] = '\0'; // dont truncate } yylval.yy_pSymName = pMidlLexTable->LexInsert(tokptr_G); SymKey SKey( yylval.yy_pSymName, NAME_DEF ); if( pBaseSymTbl->SymSearch( SKey ) ) { return TYPENAME; } else { SKey.SetKind( NAME_SDEFINE ); TEXT_SUB *pT; TEXT_BUFFER *pB; if( pT = (TEXT_SUB *)pBaseSymTbl->SymSearch( SKey ) ) { pB = pT->Expand(); pImportCntrl->RegisterTextSubsObject( pB ); token = lex(); return map_token( token ); } } return IDENTIFIER; } case LBRACK: { /* Is this simple strategy ok? */ inside_rpc++; return(token); } case RBRACK: { /* Is this simple strategy ok? */ inside_rpc--; return(token); } case NUMERICCONSTANT: case KWSTRUCT: case KWUNION: case KWENUM: case LCURLY: case RCURLY: case LPAREN: case RPAREN: case SEMI: case COLON: case COMMA: case ASSIGN: case CHARACTERCONSTANT: case PLUS: case MINUS: case MULT: case DIV: case MOD: case STRING: return(token); case EOI: if(pImportCntrl->GetLexLevel() == 0) { if(pImportCntrl->GetEOIFlag()) return 0; else pImportCntrl->SetEOIFlag(); } return EOI; } #if 0 printf("UNMAPPED token: %d\n", token); #endif // 0 return(token); } void lex_error(int number) { printf("lex error : %d\n", number); }