306 lines
5.6 KiB
Plaintext
306 lines
5.6 KiB
Plaintext
|
|
|||
|
/* SCCSWHAT( "@(#)grammar.y 1.4 89/05/09 21:22:03 " ) */
|
|||
|
|
|||
|
/*****************************************************************************/
|
|||
|
/** Microsoft LAN Manager **/
|
|||
|
/** Copyright(c) Microsoft Corp., 1987-1990 **/
|
|||
|
/*****************************************************************************/
|
|||
|
%{
|
|||
|
|
|||
|
/****************************************************************************
|
|||
|
*** local defines
|
|||
|
***************************************************************************/
|
|||
|
|
|||
|
#define pascal
|
|||
|
#define FARDATA
|
|||
|
#define NEARDATA
|
|||
|
#define FARCODE
|
|||
|
#define NEARCODE
|
|||
|
#define NEARSWAP
|
|||
|
|
|||
|
#define PASCAL pascal
|
|||
|
#define CDECL
|
|||
|
#define VOID void
|
|||
|
#define CONST const
|
|||
|
#define GLOBAL
|
|||
|
|
|||
|
#define YYSTYPE lextype_t
|
|||
|
#define YYNEAR NEARCODE
|
|||
|
#define YYPASCAL PASCAL
|
|||
|
#define YYPRINT printf
|
|||
|
#define YYSTATIC static
|
|||
|
#define YYLEX yylex
|
|||
|
#define YYPARSER yyparse
|
|||
|
|
|||
|
#define MAXARRAY 1000
|
|||
|
#define CASE_BUFFER_SIZE 10000
|
|||
|
|
|||
|
#define CASE_FN_FORMAT ("\nstatic void\ncase_fn_%.4d()")
|
|||
|
#define DISPATCH_ENTRY_FORMAT ("\n\t,case_fn_%.4d")
|
|||
|
#define DISPATCH_FIRST_ENTRY ("\n\t case_fn_%.4d")
|
|||
|
|
|||
|
/****************************************************************************
|
|||
|
*** include files
|
|||
|
***************************************************************************/
|
|||
|
|
|||
|
#include <stdio.h>
|
|||
|
#include <stdlib.h>
|
|||
|
#include <string.h>
|
|||
|
#include <ctype.h>
|
|||
|
#include <assert.h>
|
|||
|
#include "lex.h"
|
|||
|
|
|||
|
/****************************************************************************
|
|||
|
*** externals
|
|||
|
***************************************************************************/
|
|||
|
|
|||
|
extern int Incase;
|
|||
|
extern int ActionSensed;
|
|||
|
extern int yylex();
|
|||
|
extern int yyparse();
|
|||
|
|
|||
|
/****************************************************************************
|
|||
|
*** local procs
|
|||
|
***************************************************************************/
|
|||
|
|
|||
|
void Init( void );
|
|||
|
void EmitCaseTableArray( void );
|
|||
|
void EmitDefaultCase( void );
|
|||
|
void EmitCaseBody( int );
|
|||
|
void RegisterCase( int );
|
|||
|
void BufferIt( char * pStr, int iLen );
|
|||
|
void ResetBuffer();
|
|||
|
void FlushBuffer();
|
|||
|
|
|||
|
/****************************************************************************
|
|||
|
*** local data
|
|||
|
***************************************************************************/
|
|||
|
|
|||
|
unsigned long SavedIDCount = 0;
|
|||
|
unsigned long IDCount = 0;
|
|||
|
unsigned char CaseTable[ MAXARRAY ] = { 0 };
|
|||
|
int CaseNumber = 0;
|
|||
|
int MaxCaseNumber = 0;
|
|||
|
char * pBufStart;
|
|||
|
char * pBufCur;
|
|||
|
char * pBufEnd;
|
|||
|
|
|||
|
%}
|
|||
|
|
|||
|
%token ID
|
|||
|
%token NUMBER
|
|||
|
%token TOKEN_CASE
|
|||
|
%token TOKEN_CHAR
|
|||
|
%token TOKEN_END
|
|||
|
%token TOKEN_END_CASE
|
|||
|
%token TOKEN_MYACT
|
|||
|
%token TOKEN_START
|
|||
|
|
|||
|
%type <yynumber> NUMBER
|
|||
|
%type <yycharval> TOKEN_CHAR
|
|||
|
%type <yystring> ID
|
|||
|
|
|||
|
%%
|
|||
|
|
|||
|
Template:
|
|||
|
OptionalJunk TOKEN_START
|
|||
|
{
|
|||
|
Init();
|
|||
|
}
|
|||
|
OptionalJunk Body OptionalJunk TOKEN_END OptionalJunk
|
|||
|
{
|
|||
|
EmitDefaultCase();
|
|||
|
EmitCaseTableArray();
|
|||
|
}
|
|||
|
;
|
|||
|
Body:
|
|||
|
TOKEN_MYACT
|
|||
|
{
|
|||
|
ActionSensed++;
|
|||
|
ResetBuffer();
|
|||
|
}
|
|||
|
OptionalJunk CaseList
|
|||
|
{
|
|||
|
}
|
|||
|
;
|
|||
|
|
|||
|
CaseList:
|
|||
|
CaseList OneCase
|
|||
|
{
|
|||
|
}
|
|||
|
| OneCase
|
|||
|
{
|
|||
|
}
|
|||
|
;
|
|||
|
|
|||
|
OneCase:
|
|||
|
TOKEN_CASE TOKEN_CHAR NUMBER TOKEN_CHAR
|
|||
|
{
|
|||
|
Incase = 1;
|
|||
|
|
|||
|
CaseNumber = $3;
|
|||
|
if($3 >= MAXARRAY)
|
|||
|
{
|
|||
|
fprintf(stderr, "Case Limit Reached : Contact Dov/Vibhas\n");
|
|||
|
return 1;
|
|||
|
}
|
|||
|
|
|||
|
SavedIDCount = IDCount;
|
|||
|
}
|
|||
|
OptionalJunk TOKEN_END_CASE
|
|||
|
{
|
|||
|
if(SavedIDCount != IDCount)
|
|||
|
{
|
|||
|
RegisterCase( CaseNumber );
|
|||
|
EmitCaseBody( CaseNumber );
|
|||
|
}
|
|||
|
|
|||
|
ResetBuffer();
|
|||
|
|
|||
|
if(CaseNumber > MaxCaseNumber)
|
|||
|
MaxCaseNumber = CaseNumber;
|
|||
|
Incase = 0;
|
|||
|
}
|
|||
|
;
|
|||
|
|
|||
|
OptionalJunk:
|
|||
|
Junk
|
|||
|
{
|
|||
|
}
|
|||
|
| /* Empty */
|
|||
|
{
|
|||
|
}
|
|||
|
;
|
|||
|
|
|||
|
Junk:
|
|||
|
Junk JunkElement
|
|||
|
{
|
|||
|
}
|
|||
|
| JunkElement
|
|||
|
{
|
|||
|
}
|
|||
|
;
|
|||
|
|
|||
|
JunkElement:
|
|||
|
TOKEN_CHAR
|
|||
|
{
|
|||
|
if(!ActionSensed)
|
|||
|
fprintf(stdout, "%c", $1);
|
|||
|
else
|
|||
|
BufferIt( &$1, 1);
|
|||
|
}
|
|||
|
| ID
|
|||
|
{
|
|||
|
IDCount++;
|
|||
|
if(!ActionSensed)
|
|||
|
fprintf(stdout, "%s", $1);
|
|||
|
else
|
|||
|
BufferIt( $1, strlen($1) );
|
|||
|
}
|
|||
|
| NUMBER
|
|||
|
{
|
|||
|
if(!ActionSensed)
|
|||
|
fprintf(stdout, "%d", $1);
|
|||
|
else
|
|||
|
{
|
|||
|
char buffer[20];
|
|||
|
sprintf(buffer,"%d", $1 );
|
|||
|
BufferIt( buffer, strlen(buffer) );
|
|||
|
}
|
|||
|
}
|
|||
|
;
|
|||
|
|
|||
|
%%
|
|||
|
|
|||
|
/*****************************************************************************
|
|||
|
* utility functions
|
|||
|
*****************************************************************************/
|
|||
|
YYSTATIC VOID FARCODE PASCAL
|
|||
|
yyerror(char *szError)
|
|||
|
{
|
|||
|
extern int Line;
|
|||
|
extern char LocalBuffer[];
|
|||
|
|
|||
|
fprintf(stderr, "%s at Line %d near %s\n", szError, Line, LocalBuffer);
|
|||
|
}
|
|||
|
void
|
|||
|
Init()
|
|||
|
{
|
|||
|
pBufStart = pBufCur = malloc( CASE_BUFFER_SIZE );
|
|||
|
if( !pBufStart )
|
|||
|
{
|
|||
|
fprintf(stderr,"Out Of Memory\n");
|
|||
|
exit(1);
|
|||
|
}
|
|||
|
pBufEnd = pBufStart + CASE_BUFFER_SIZE;
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
BufferIt(
|
|||
|
char * pStr,
|
|||
|
int iLen )
|
|||
|
{
|
|||
|
if( pBufCur + iLen > pBufEnd )
|
|||
|
{
|
|||
|
printf("ALERT iLen = %d\n", iLen );
|
|||
|
// assert( (pBufCur + iLen) <= pBufEnd );
|
|||
|
exit(1);
|
|||
|
}
|
|||
|
strncpy( pBufCur , pStr, iLen );
|
|||
|
pBufCur += iLen;
|
|||
|
*pBufCur = '\0';
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
ResetBuffer()
|
|||
|
{
|
|||
|
pBufCur = pBufStart;
|
|||
|
*pBufCur= '\0';
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
FlushBuffer()
|
|||
|
{
|
|||
|
fprintf(stdout, "%s", pBufStart);
|
|||
|
ResetBuffer();
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
EmitCaseBody(
|
|||
|
int CaseNumber )
|
|||
|
{
|
|||
|
fprintf( stdout, CASE_FN_FORMAT, CaseNumber );
|
|||
|
FlushBuffer();
|
|||
|
fprintf( stdout, "}\n" );
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
EmitCaseTableArray()
|
|||
|
{
|
|||
|
int i, iTemp;
|
|||
|
|
|||
|
fprintf( stdout, "static void\t (*case_fn_array[])() = \n\t{" );
|
|||
|
fprintf( stdout,DISPATCH_FIRST_ENTRY, 0 );
|
|||
|
|
|||
|
for( i = 1 ; i <= MaxCaseNumber ; ++i )
|
|||
|
{
|
|||
|
iTemp = CaseTable[ i ] ? i : 0;
|
|||
|
fprintf(stdout,DISPATCH_ENTRY_FORMAT, iTemp );
|
|||
|
}
|
|||
|
|
|||
|
fprintf( stdout, "\n\t};\n" );
|
|||
|
fprintf( stdout, "\nstatic void\nyy_vc_init(){ pcase_fn_array = case_fn_array;\nyym_vc_max = %d;\n }\n" , MaxCaseNumber);
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
EmitDefaultCase()
|
|||
|
{
|
|||
|
fprintf(stdout, "static void\ncase_fn_%.4d() {\n\t}\n\n", 0 );
|
|||
|
}
|
|||
|
void
|
|||
|
RegisterCase(
|
|||
|
int iCase )
|
|||
|
{
|
|||
|
CaseTable[ iCase ] = 1;
|
|||
|
}
|