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.
167 lines
5.1 KiB
167 lines
5.1 KiB
THE IMPORT FILE HANDLER
|
|
-----------------------
|
|
|
|
The import statement permits a user to import types from
|
|
another interface file. The behavior thus is like a
|
|
pre-processor include statement in C, but semantically, the
|
|
compiler needs to process it different from just a textual
|
|
include. These aspects have to be kept in mind:
|
|
|
|
A) The import file handler must have support for the
|
|
following:
|
|
|
|
1. Multiple (nested) inclusions of import files
|
|
2. Mulitple (non-nested) inclusions of import files
|
|
|
|
In other words, the following statement must result in import
|
|
of foo2 and foo3 assuming that we are compiling foo1.idl
|
|
|
|
IMPORT "foo2" (in foo1.idl)
|
|
|
|
where foo2 has an import statement saying:
|
|
|
|
IMPORT "foo3" (in foo2.idl)
|
|
|
|
Also, a similar case must occur when the following statement appears
|
|
in foo1.idl
|
|
|
|
IMPORT "foo2" , "foo3" (in foo1.idl)
|
|
|
|
B) NIDL does not specify the number of nested import files that
|
|
the user can have. This is implementation dependent. The physical
|
|
behaviour being similar to a textual include (maybe nested) the
|
|
problem lies in the number of open import files that the system lets
|
|
the compiler keep open. Under DOS this limit can be as low as 15.
|
|
Since only one include file need be kept open at a time, the compiler
|
|
needs to manage closing of the import files, re-opening and so on.
|
|
|
|
C) The parser or lexer may need to know the line and column position
|
|
within the file to be able to report errors as close to their occurence
|
|
as possible, as also know which import file they occured in.
|
|
|
|
|
|
THE IMPORT FILE STATUS STACK
|
|
----------------------------
|
|
|
|
The import file status stack is the mechanism by which the import file
|
|
is handled. The import file handler presents a black-box like interface
|
|
to the lexer and parser.
|
|
Internally each import file stack element looks like this :
|
|
|
|
typedef struct _import_stack
|
|
{
|
|
|
|
FILE *hFile;
|
|
unsigned long ulPos;
|
|
unsigned short uLine; -| these two may be discarded
|
|
unsigned short uCol; _| if not needed
|
|
char *pName;
|
|
unsigned short uFlags;
|
|
|
|
}IMPORT_STACK;
|
|
|
|
hFile: This is the handle to the import file. This info
|
|
is current only till the file is open
|
|
ulPos: The position in the file. In case the import file
|
|
handler needs to close a file to reuse a file handle
|
|
this is the position to come back to.
|
|
uLine: The current line and column number. The error handler
|
|
may need to know the position in terms of the line
|
|
and column, to report an error. This provides the
|
|
means.
|
|
uCol: The column number for error reporting
|
|
pName: Filename to open the file with.
|
|
uFlags: Currently the only use of this is for the purpose
|
|
of identifying if the file is closed or open . If
|
|
it is closed , it needs to be opened and set to
|
|
ulPos. This is useful for occasions where deep nesting
|
|
of imports results in running out of file handles and
|
|
some may need to be closed to be re-opened later.
|
|
|
|
The stack is thus defined as:
|
|
|
|
IMPORT_STACK ImportStack[ MAX_NESTED_IMPORTS ];
|
|
|
|
In addition we need to keep track of the current import nesting level
|
|
in a variable static to the import file handler module.
|
|
|
|
More detailed interfaces are yet to be decided. Currenlty the interface
|
|
looks like:
|
|
|
|
void SetImportFile( char *pName );
|
|
To set the import file to the file whose
|
|
name is specified. The current file is
|
|
closed.
|
|
|
|
void PushImportLevel()
|
|
As a result of nested import statement, this
|
|
level of import is incremented. This is
|
|
followed by a SetImportFile call.
|
|
|
|
void PopImportLevel()
|
|
End of current import file seen. Restore
|
|
import level to previous, continue input
|
|
from the last import file,if that is not
|
|
open, open it.
|
|
|
|
unsigned short GetImportLevel()
|
|
Return the current import level. This may
|
|
be needed for housekeeping purposes or error
|
|
reporting
|
|
|
|
char *pszGetCurrentImportFName()
|
|
Return the name of the file from which the
|
|
import is in progress. May be needed for
|
|
housekeeping or error reporting.
|
|
|
|
To explain how the parser interfaces with the import file manager
|
|
here is a small grammar fragment dealing with imports and its
|
|
relevant semantic actions: (This is only representative of the
|
|
way the parser deals with the import scheme. The actual imp-
|
|
lemenation may be different. It also does not show all aspects
|
|
of the interface e.g the error reporting ).
|
|
|
|
RpcImports :
|
|
{
|
|
/***
|
|
*** No import file was seen, do nothing here
|
|
***/
|
|
}
|
|
| IMPORT
|
|
{
|
|
/***
|
|
*** PushImportLevel(); /* import prologue */
|
|
***/
|
|
}
|
|
ImportList
|
|
{
|
|
/***
|
|
*** PopImportLevel(); /* import epilogue */
|
|
***/
|
|
}
|
|
;
|
|
|
|
ImportList : ImportList ',' OneImport
|
|
{
|
|
/***
|
|
*** No action here. Action for any import is taken
|
|
*** only at the OneImport production
|
|
***/
|
|
}
|
|
| OneImport
|
|
{
|
|
/***
|
|
*** No action here. Action for any import is taken
|
|
*** only at the OneImport production
|
|
***/
|
|
}
|
|
;
|
|
|
|
OneImport : STRING RPCProg
|
|
{
|
|
/***
|
|
*** SetImportFile( $1.ptr); /* assuming $1 returns a
|
|
*** pointer to string */
|
|
***/
|
|
}
|
|
;
|