📄 eiffel.c
字号:
static void findFeatureEnd (tokenInfo *const token)
{
readToken (token);
switch (token->keyword)
{
default:
if (isType (token, TOKEN_OPERATOR)) /* sign of manifest constant */
readToken (token);
readToken (token); /* skip to next token after constant */
break;
case KEYWORD_deferred:
case KEYWORD_do:
case KEYWORD_external:
case KEYWORD_local:
case KEYWORD_obsolete:
case KEYWORD_once:
case KEYWORD_require:
{
int depth = 1;
while (depth > 0)
{
#ifdef TYPE_REFERENCE_TOOL
if (isType (token, TOKEN_OPEN_BRACE))
{
readToken (token);
if (isType (token, TOKEN_IDENTIFIER))
parseType (token);
if (isType (token, TOKEN_CLOSE_BRACE))
readToken (token);
}
else if (isType (token, TOKEN_BANG))
{
readToken (token);
if (isType (token, TOKEN_IDENTIFIER))
parseType (token);
if (isType (token, TOKEN_BANG))
readToken (token);
}
else
#endif
switch (token->keyword)
{
case KEYWORD_check:
case KEYWORD_debug:
case KEYWORD_from:
case KEYWORD_if:
case KEYWORD_inspect:
++depth;
break;
case KEYWORD_local:
parseLocal (token);
break;
case KEYWORD_end:
--depth;
break;
default:
break;
}
readToken (token);
}
break;
}
}
}
static boolean readFeatureName (tokenInfo *const token)
{
boolean isFeatureName = FALSE;
if (isKeyword (token, KEYWORD_frozen))
readToken (token);
if (isType (token, TOKEN_IDENTIFIER))
isFeatureName = TRUE;
else if (isKeyword (token, KEYWORD_infix) ||
isKeyword (token, KEYWORD_prefix))
{
readToken (token);
if (isType (token, TOKEN_STRING))
isFeatureName = TRUE;
}
return isFeatureName;
}
static void parseArguments (tokenInfo *const token)
{
#ifndef TYPE_REFERENCE_TOOL
findToken (token, TOKEN_CLOSE_PAREN);
readToken (token);
#else
Assert (isType (token, TOKEN_OPEN_PAREN));
readToken (token);
do
{
if (! isType (token, TOKEN_COLON))
readToken (token);
else
{
readToken (token);
if (isType (token, TOKEN_IDENTIFIER))
parseType (token);
}
} while (! isType (token, TOKEN_CLOSE_PAREN));
readToken (token);
#endif
}
static boolean parseFeature (tokenInfo *const token)
{
boolean found = FALSE;
while (readFeatureName (token))
{
found = TRUE;
#ifndef TYPE_REFERENCE_TOOL
makeEiffelFeatureTag (token);
#endif
readToken (token);
if (isType (token, TOKEN_COMMA))
readToken (token);
}
if (found)
{
if (isType (token, TOKEN_OPEN_PAREN)) /* arguments? */
parseArguments (token);
if (isType (token, TOKEN_COLON)) /* a query? */
parseEntityType (token);
if (isKeyword (token, KEYWORD_obsolete))
{
readToken (token);
if (isType (token, TOKEN_STRING))
readToken (token);
}
if (isKeyword (token, KEYWORD_is))
findFeatureEnd (token);
}
return found;
}
static void parseExport (tokenInfo *const token)
{
token->isExported = TRUE;
readToken (token);
if (isType (token, TOKEN_OPEN_BRACE))
{
token->isExported = FALSE;
while (! isType (token, TOKEN_CLOSE_BRACE))
{
if (isType (token, TOKEN_IDENTIFIER))
token->isExported |= !isIdentifierMatch (token, "NONE");
readToken (token);
}
readToken (token);
}
}
static void parseFeatureClauses (tokenInfo *const token)
{
Assert (isKeyword (token, KEYWORD_feature));
do
{
if (isKeyword (token, KEYWORD_feature))
parseExport (token);
if (! isKeyword (token, KEYWORD_feature) &&
! isKeyword (token, KEYWORD_invariant) &&
! isKeyword (token, KEYWORD_indexing))
{
if (! parseFeature (token))
readToken (token);
}
} while (! isKeyword (token, KEYWORD_end) &&
! isKeyword (token, KEYWORD_invariant) &&
! isKeyword (token, KEYWORD_indexing));
}
static void parseRename (tokenInfo *const token)
{
do {
readToken (token);
if (readFeatureName (token))
{
readToken (token);
if (isKeyword (token, KEYWORD_as))
{
readToken (token);
if (readFeatureName (token))
{
#ifndef TYPE_REFERENCE_TOOL
makeEiffelFeatureTag (token); /* renamed feature */
#endif
readToken (token);
}
}
}
} while (isType (token, TOKEN_COMMA));
findKeyword (token, KEYWORD_end);
readToken (token);
}
static void parseInherit (tokenInfo *const token)
{
Assert (isKeyword (token, KEYWORD_inherit));
#ifdef TYPE_REFERENCE_TOOL
readToken (token);
while (isType (token, TOKEN_IDENTIFIER))
{
parseType (token);
if (isType (token, TOKEN_KEYWORD))
{
switch (token->keyword) /* check for feature adaptation */
{
case KEYWORD_rename:
case KEYWORD_export:
case KEYWORD_undefine:
case KEYWORD_redefine:
case KEYWORD_select:
findKeyword (token, KEYWORD_end);
readToken (token);
default: break;
}
}
}
#else
readToken (token);
while (isType (token, TOKEN_IDENTIFIER))
{
parseType (token);
switch (token->keyword) /* check for feature adaptation */
{
case KEYWORD_rename:
parseRename (token);
if (isKeyword (token, KEYWORD_end))
readToken (token);
break;
case KEYWORD_export:
case KEYWORD_undefine:
case KEYWORD_redefine:
case KEYWORD_select:
findKeyword (token, KEYWORD_end);
readToken (token);
break;
case KEYWORD_end:
readToken (token);
break;
default: break;
}
}
#endif
}
static void parseClass (tokenInfo *const token)
{
Assert (isKeyword (token, KEYWORD_class));
readToken (token);
if (isType (token, TOKEN_IDENTIFIER))
{
#ifndef TYPE_REFERENCE_TOOL
makeEiffelClassTag (token);
readToken (token);
#else
vStringCopy (token->className, token->string);
if (PrintClass)
puts (vStringValue (token->className));
if (! PrintReferences)
exit (0);
readToken (token);
#endif
}
do
{
if (isType (token, TOKEN_OPEN_BRACKET))
parseGeneric (token, TRUE);
else if (! isType (token, TOKEN_KEYWORD))
readToken (token);
else switch (token->keyword)
{
case KEYWORD_inherit: parseInherit (token); break;
case KEYWORD_feature: parseFeatureClauses (token); break;
default: readToken (token); break;
}
} while (! isKeyword (token, KEYWORD_end));
}
static tokenInfo *newToken (void)
{
tokenInfo *const token = xMalloc (1, tokenInfo);
token->type = TOKEN_UNDEFINED;
token->keyword = KEYWORD_NONE;
token->isExported = TRUE;
token->string = vStringNew ();
token->className = vStringNew ();
token->featureName = vStringNew ();
return token;
}
static void deleteToken (tokenInfo *const token)
{
vStringDelete (token->string);
vStringDelete (token->className);
vStringDelete (token->featureName);
eFree (token);
}
static void initialize (const langType language)
{
Lang_eiffel = language;
buildEiffelKeywordHash ();
}
static void findEiffelTags (void)
{
tokenInfo *const token = newToken ();
exception_t exception;
exception = (exception_t) (setjmp (Exception));
while (exception == ExceptionNone)
{
findKeyword (token, KEYWORD_class);
parseClass (token);
}
deleteToken (token);
}
#ifndef TYPE_REFERENCE_TOOL
extern parserDefinition* EiffelParser (void)
{
static const char *const extensions [] = { "e", NULL };
parserDefinition* def = parserNew ("Eiffel");
def->kinds = EiffelKinds;
def->kindCount = KIND_COUNT (EiffelKinds);
def->extensions = extensions;
def->parser = findEiffelTags;
def->initialize = initialize;
return def;
}
#else
static void findReferences (void)
{
ReferencedTypes = stringListNew ();
GenericNames = stringListNew ();
initialize (0);
findEiffelTags ();
stringListDelete (GenericNames);
GenericNames = NULL;
stringListDelete (ReferencedTypes);
ReferencedTypes = NULL;
}
static const char *const Usage =
"Prints names of types referenced by an Eiffel language file.\n"
"\n"
"Usage: %s [-cdrs] [file_name | -]\n"
"\n"
"Options:\n"
" -c Print class name of current file (on first line of output).\n"
" -d Enable debug output.\n"
" -r Print types referenced by current file (default unless -c).\n"
" -s Include self-references.\n"
"\n";
extern main (int argc, char** argv)
{
int i;
for (i = 1 ; argv [i] != NULL ; ++i)
{
const char *const arg = argv [i];
if (arg [0] == '-')
{
int j;
if (arg [1] == '\0')
{
File = stdin;
FileName = "stdin";
}
else for (j = 1 ; arg [j] != '\0' ; ++j) switch (arg [j])
{
case 'c': PrintClass = 1; break;
case 'r': PrintReferences = 1; break;
case 's': SelfReferences = 1; break;
case 'd': Debug = 1; break;
default:
fprintf (errout, "%s: unknown option: %c\n", argv [0], arg [1]);
fprintf (errout, Usage, argv [0]);
exit (1);
break;
}
}
else if (File != NULL)
{
fprintf (errout, Usage, argv [0]);
exit (1);
}
else
{
FileName = arg;
File = fopen (FileName, "r");
if (File == NULL)
{
perror (argv [0]);
exit (1);
}
}
}
if (! PrintClass)
PrintReferences = 1;
if (File == NULL)
{
fprintf (errout, Usage, argv [0]);
exit (1);
}
findReferences ();
}
#endif
/* vi:set tabstop=8 shiftwidth=4: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -