mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
366 lines
8.1 KiB
366 lines
8.1 KiB
/*
|
|
** helper functions for Gerd Immeyer's grammar
|
|
**
|
|
*/
|
|
|
|
/****************************************************************************
|
|
* include files
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#include "nulldefs.h"
|
|
extern "C" {
|
|
#include <stdio.h>
|
|
#include <io.h>
|
|
#include <process.h>
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
}
|
|
|
|
#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);
|
|
}
|