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;
|
||
}
|