⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eiffel.c

📁 ultraEdit的Ctag标签工具的实现源代码
💻 C
📖 第 1 页 / 共 3 页
字号:

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 + -