xref: /Universal-ctags/parsers/r-s4class.c (revision cd90567899eac84aa3a28b1598f70cdd1d9ab332)
11ce09ad9SMasatake YAMATO /*
21ce09ad9SMasatake YAMATO *   Copyright (c) 2020, Masatake YAMATO
31ce09ad9SMasatake YAMATO *   Copyright (c) 2020, Red Hat, Inc.
41ce09ad9SMasatake YAMATO *
51ce09ad9SMasatake YAMATO *   This source code is released for free distribution under the terms of the
61ce09ad9SMasatake YAMATO *   GNU General Public License version 2 or (at your option) any later version.
71ce09ad9SMasatake YAMATO *
81ce09ad9SMasatake YAMATO *   This module contains functions for generating tags for S4 Classes and Methods.
91ce09ad9SMasatake YAMATO *   https://www.r-project.org/conferences/useR-2004/Keynotes/Leisch.pdf
101ce09ad9SMasatake YAMATO */
111ce09ad9SMasatake YAMATO 
121ce09ad9SMasatake YAMATO 
131ce09ad9SMasatake YAMATO /*
141ce09ad9SMasatake YAMATO *   INCLUDE FILES
151ce09ad9SMasatake YAMATO */
161ce09ad9SMasatake YAMATO #include "general.h"	/* must always come first */
171ce09ad9SMasatake YAMATO 
181ce09ad9SMasatake YAMATO #include "r.h"
191ce09ad9SMasatake YAMATO #include "kind.h"
201ce09ad9SMasatake YAMATO #include "tokeninfo.h"
211ce09ad9SMasatake YAMATO #include "parse.h"
221ce09ad9SMasatake YAMATO #include "subparser.h"
231ce09ad9SMasatake YAMATO 
241ce09ad9SMasatake YAMATO #include <string.h>
251ce09ad9SMasatake YAMATO 
261ce09ad9SMasatake YAMATO 
271ce09ad9SMasatake YAMATO /*
281ce09ad9SMasatake YAMATO *   DATA DECLARATIONS
291ce09ad9SMasatake YAMATO */
301ce09ad9SMasatake YAMATO 
311ce09ad9SMasatake YAMATO struct s4Subparser {
321ce09ad9SMasatake YAMATO 	rSubparser r;
331ce09ad9SMasatake YAMATO };
341ce09ad9SMasatake YAMATO 
351ce09ad9SMasatake YAMATO 
361ce09ad9SMasatake YAMATO /*
371ce09ad9SMasatake YAMATO * FUNCTION PROTOTYPES
381ce09ad9SMasatake YAMATO */
391ce09ad9SMasatake YAMATO 
401ce09ad9SMasatake YAMATO static int s4ReadFuncall (rSubparser *s,
411ce09ad9SMasatake YAMATO 						  tokenInfo *const func, tokenInfo *const token,
421ce09ad9SMasatake YAMATO 						  int parent);
431ce09ad9SMasatake YAMATO static int s4ReadRightSideSymbol (rSubparser *s,
441ce09ad9SMasatake YAMATO 								  tokenInfo *const symbol,
451ce09ad9SMasatake YAMATO 								  const char *const assignmentOperator,
461ce09ad9SMasatake YAMATO 								  int parent,
471ce09ad9SMasatake YAMATO 								  tokenInfo *const token);
481ce09ad9SMasatake YAMATO static bool s4AskTagAcceptancy (rSubparser *s, tagEntryInfo *pe);
49582f04dcSMasatake YAMATO static bool s4HasFunctionAlikeKind (rSubparser *s, tagEntryInfo *e);
501ce09ad9SMasatake YAMATO 
511ce09ad9SMasatake YAMATO 
521ce09ad9SMasatake YAMATO /*
531ce09ad9SMasatake YAMATO *   DATA DEFINITIONS
541ce09ad9SMasatake YAMATO */
551ce09ad9SMasatake YAMATO 
561ce09ad9SMasatake YAMATO typedef enum {
571ce09ad9SMasatake YAMATO 	S4_K_CLASS,
581ce09ad9SMasatake YAMATO 	S4_K_REPRESENTATION,
591ce09ad9SMasatake YAMATO 	S4_K_GENERIC,
601ce09ad9SMasatake YAMATO 	S4_K_METHOD,
611ce09ad9SMasatake YAMATO } s4Kind;
621ce09ad9SMasatake YAMATO 
631ce09ad9SMasatake YAMATO static kindDefinition S4Kinds[] = {
641ce09ad9SMasatake YAMATO 	{ true, 'c', "class",   "classes" },
651ce09ad9SMasatake YAMATO 	{ true, 'r', "repr",    "representations" },
661ce09ad9SMasatake YAMATO 	{ true, 'g', "generic", "generics" },
671ce09ad9SMasatake YAMATO 	{ true, 'm', "method",  "methods" },
681ce09ad9SMasatake YAMATO };
691ce09ad9SMasatake YAMATO 
701ce09ad9SMasatake YAMATO static struct s4Subparser s4Subparser = {
711ce09ad9SMasatake YAMATO 	.r = {
721ce09ad9SMasatake YAMATO 		.subparser = {
731ce09ad9SMasatake YAMATO 			.direction = SUBPARSER_BI_DIRECTION,
741ce09ad9SMasatake YAMATO 		},
751ce09ad9SMasatake YAMATO 		.readFuncall = s4ReadFuncall,
761ce09ad9SMasatake YAMATO 		.readRightSideSymbol = s4ReadRightSideSymbol,
771ce09ad9SMasatake YAMATO 		.askTagAcceptancy = s4AskTagAcceptancy,
78582f04dcSMasatake YAMATO 		.hasFunctionAlikeKind = s4HasFunctionAlikeKind,
791ce09ad9SMasatake YAMATO 	},
801ce09ad9SMasatake YAMATO };
811ce09ad9SMasatake YAMATO 
821ce09ad9SMasatake YAMATO 
831ce09ad9SMasatake YAMATO /*
841ce09ad9SMasatake YAMATO *   FUNCTION DEFINITIONS
851ce09ad9SMasatake YAMATO */
861ce09ad9SMasatake YAMATO 
871ce09ad9SMasatake YAMATO /*
881ce09ad9SMasatake YAMATO  * V=================V: parse this area
891ce09ad9SMasatake YAMATO  * representation(...)) ...
901ce09ad9SMasatake YAMATO  * representation(...), ...
911ce09ad9SMasatake YAMATO  */
parseRepresentation(rSubparser * s,tokenInfo * const token,int parent)921ce09ad9SMasatake YAMATO static void parseRepresentation (rSubparser *s, tokenInfo *const token, int parent)
931ce09ad9SMasatake YAMATO {
941ce09ad9SMasatake YAMATO 	rTokenReadNoNewline (token);
951ce09ad9SMasatake YAMATO 	if (tokenIsTypeVal (token, '('))
961ce09ad9SMasatake YAMATO 	{
971ce09ad9SMasatake YAMATO 		rTokenReadNoNewline (token);
9819bff7a2SMasatake YAMATO 		while (!(tokenIsTypeVal (token, ')') || tokenIsTypeVal (token, ',')))
991ce09ad9SMasatake YAMATO 		{
10019bff7a2SMasatake YAMATO 			if (!rParseStatement (token, parent, false))
10119bff7a2SMasatake YAMATO 				break;
10219bff7a2SMasatake YAMATO 			else if (tokenIsTypeVal (token, '\n'))
1031ce09ad9SMasatake YAMATO 				rTokenReadNoNewline (token);
1041ce09ad9SMasatake YAMATO 		}
1051ce09ad9SMasatake YAMATO 	}
1061ce09ad9SMasatake YAMATO 	else
1071ce09ad9SMasatake YAMATO 		tokenUnread (token);
1081ce09ad9SMasatake YAMATO }
1091ce09ad9SMasatake YAMATO 
1101ce09ad9SMasatake YAMATO /*
1111ce09ad9SMasatake YAMATO  * V==============V: parse this area
1121ce09ad9SMasatake YAMATO  * contains = "..."
1131ce09ad9SMasatake YAMATO  */
parseContains(rSubparser * s,tokenInfo * const token,int parent)1141ce09ad9SMasatake YAMATO static void parseContains (rSubparser *s, tokenInfo *const token, int parent)
1151ce09ad9SMasatake YAMATO {
1161ce09ad9SMasatake YAMATO 	rTokenReadNoNewline (token);
1171ce09ad9SMasatake YAMATO 	if (tokenIsTypeVal (token, '='))
1181ce09ad9SMasatake YAMATO 	{
1191ce09ad9SMasatake YAMATO 		rTokenReadNoNewline (token);
1201ce09ad9SMasatake YAMATO 		if (tokenIsType (token, R_STRING))
1211ce09ad9SMasatake YAMATO 		{
1221ce09ad9SMasatake YAMATO 			tagEntryInfo *e = getEntryInCorkQueue (parent);
1231ce09ad9SMasatake YAMATO 			if (e)
1241ce09ad9SMasatake YAMATO 			{
1251ce09ad9SMasatake YAMATO 				vString *n = rExtractNameFromString (token->string);
1261ce09ad9SMasatake YAMATO 				e->extensionFields.inheritance = vStringDeleteUnwrap (n);
1271ce09ad9SMasatake YAMATO 			}
1281ce09ad9SMasatake YAMATO 		}
1291ce09ad9SMasatake YAMATO 		else
1301ce09ad9SMasatake YAMATO 			tokenUnread (token);
1311ce09ad9SMasatake YAMATO 	}
1321ce09ad9SMasatake YAMATO 	else
1331ce09ad9SMasatake YAMATO 		tokenUnread (token);
1341ce09ad9SMasatake YAMATO }
1351ce09ad9SMasatake YAMATO 
1361ce09ad9SMasatake YAMATO /*
1371ce09ad9SMasatake YAMATO  *                  V====V: parse this area
1381ce09ad9SMasatake YAMATO  * setClass ("class", ...)
1391ce09ad9SMasatake YAMATO  */
parseClassArgs(rSubparser * s,tokenInfo * const token,int parent,tokenInfo * const open_paren CTAGS_ATTR_UNUSED)1401ce09ad9SMasatake YAMATO static bool parseClassArgs (rSubparser *s, tokenInfo *const token, int parent,
1411ce09ad9SMasatake YAMATO 							tokenInfo *const open_paren CTAGS_ATTR_UNUSED)
1421ce09ad9SMasatake YAMATO {
1431ce09ad9SMasatake YAMATO 	do
1441ce09ad9SMasatake YAMATO 	{
1451ce09ad9SMasatake YAMATO 		rTokenReadNoNewline (token);
1461ce09ad9SMasatake YAMATO 
1471ce09ad9SMasatake YAMATO 		if (tokenIsTypeVal (token, ')'))
1481ce09ad9SMasatake YAMATO 			break;
1491ce09ad9SMasatake YAMATO 		else if (tokenIsTypeVal (token, '('))
1501ce09ad9SMasatake YAMATO 			tokenSkipOverPair (token);
1511ce09ad9SMasatake YAMATO 		else if (tokenIsTypeVal (token, '{'))
1521ce09ad9SMasatake YAMATO 			tokenSkipOverPair (token);
1531ce09ad9SMasatake YAMATO 		else if (tokenIsTypeVal (token, '['))
1541ce09ad9SMasatake YAMATO 			tokenSkipOverPair (token);
1551ce09ad9SMasatake YAMATO 		else if (tokenIsType (token, R_SYMBOL))
1561ce09ad9SMasatake YAMATO 		{
1571ce09ad9SMasatake YAMATO 			const char *str = tokenString (token);
1581ce09ad9SMasatake YAMATO 			if (strcmp (str, "representation") == 0)
1591ce09ad9SMasatake YAMATO 				parseRepresentation (s, token, parent);
1601ce09ad9SMasatake YAMATO 			else if (strcmp (str, "contains") == 0)
1611ce09ad9SMasatake YAMATO 				parseContains (s, token, parent);
1621ce09ad9SMasatake YAMATO 		}
1631ce09ad9SMasatake YAMATO 	}
1641ce09ad9SMasatake YAMATO 	while (!tokenIsEOF (token));
1651ce09ad9SMasatake YAMATO 
1661ce09ad9SMasatake YAMATO 	return false;
1671ce09ad9SMasatake YAMATO }
1681ce09ad9SMasatake YAMATO 
1691ce09ad9SMasatake YAMATO /*
1701ce09ad9SMasatake YAMATO  *                    V============V: parse this area
1711ce09ad9SMasatake YAMATO  * setMethod ("method", c(...), ...)
1721ce09ad9SMasatake YAMATO  *                    V====================V: parse this area
1731ce09ad9SMasatake YAMATO  * setMethod ("method", signature(...), ...)
1741ce09ad9SMasatake YAMATO  *
1751ce09ad9SMasatake YAMATO  * Attaching c(...) or signature(...) to "signature:" field of
1761ce09ad9SMasatake YAMATO  * the tag for "method" specified by parent.
1771ce09ad9SMasatake YAMATO  */
parseMethodArgs(rSubparser * s,tokenInfo * const token,int parent,tokenInfo * const open_paren)1781ce09ad9SMasatake YAMATO static bool parseMethodArgs (rSubparser *s, tokenInfo *const token, int parent,
1791ce09ad9SMasatake YAMATO 							 tokenInfo *const open_paren)
1801ce09ad9SMasatake YAMATO {
1811ce09ad9SMasatake YAMATO 	rTokenReadNoNewline (token);
1821ce09ad9SMasatake YAMATO 	if (tokenIsTypeVal (token, ','))
1831ce09ad9SMasatake YAMATO 	{
1841ce09ad9SMasatake YAMATO 		rTokenReadNoNewline (token);
185*cd905678SMasatake YAMATO 		if (tokenIsKeyword (token, R_C)
186*cd905678SMasatake YAMATO 			|| (tokenIsType (token, R_SYMBOL)
187*cd905678SMasatake YAMATO 				&& (strcmp (tokenString (token), "signature") == 0)))
1881ce09ad9SMasatake YAMATO 		{
1891ce09ad9SMasatake YAMATO 			rTokenReadNoNewline (token);
1901ce09ad9SMasatake YAMATO 			if (tokenIsTypeVal (token, '('))
1911ce09ad9SMasatake YAMATO 			{
1921ce09ad9SMasatake YAMATO 				vString *signature = vStringNewInit("(");
1931ce09ad9SMasatake YAMATO 				rSetupCollectingSignature (token, signature);
1941ce09ad9SMasatake YAMATO 				tokenSkipOverPair (token);
1951ce09ad9SMasatake YAMATO 				rTeardownCollectingSignature (token);
1961ce09ad9SMasatake YAMATO 				tagEntryInfo *e = getEntryInCorkQueue (parent);
1971ce09ad9SMasatake YAMATO 				if (e)
1981ce09ad9SMasatake YAMATO 				{
1991ce09ad9SMasatake YAMATO 					e->extensionFields.signature = vStringDeleteUnwrap (signature);
2001ce09ad9SMasatake YAMATO 					signature = NULL;
2011ce09ad9SMasatake YAMATO 				}
2021ce09ad9SMasatake YAMATO 				vStringDelete (signature); /* NULL is acceptable */
2031ce09ad9SMasatake YAMATO 			}
2041ce09ad9SMasatake YAMATO 			rTokenReadNoNewline (token);
2051ce09ad9SMasatake YAMATO 			if (tokenIsTypeVal (token, ','))
2061ce09ad9SMasatake YAMATO 			{
2071ce09ad9SMasatake YAMATO 				rTokenReadNoNewline (token);
2081ce09ad9SMasatake YAMATO 				/* anonymous function for implementing this method may be here.*/
20919bff7a2SMasatake YAMATO 				while (!tokenIsTypeVal (token, ')'))
2101ce09ad9SMasatake YAMATO 				{
21119bff7a2SMasatake YAMATO 					if (!rParseStatement (token, parent, true))
21219bff7a2SMasatake YAMATO 						break;
21319bff7a2SMasatake YAMATO 					else if (tokenIsTypeVal (token, '\n'))
2141ce09ad9SMasatake YAMATO 						rTokenReadNoNewline (token);
2151ce09ad9SMasatake YAMATO 				}
2161ce09ad9SMasatake YAMATO 			}
2171ce09ad9SMasatake YAMATO 			return false;
2181ce09ad9SMasatake YAMATO 		}
2191ce09ad9SMasatake YAMATO 		else
2201ce09ad9SMasatake YAMATO 			tokenUnread (token);
2211ce09ad9SMasatake YAMATO 	}
2221ce09ad9SMasatake YAMATO 	else
2231ce09ad9SMasatake YAMATO 		tokenUnread (token);
2241ce09ad9SMasatake YAMATO 	return true;
2251ce09ad9SMasatake YAMATO }
2261ce09ad9SMasatake YAMATO 
2271ce09ad9SMasatake YAMATO /*
2281ce09ad9SMasatake YAMATO  *                      V====V: parse this area
2291ce09ad9SMasatake YAMATO  * setGeneric ("generic", ...)
2301ce09ad9SMasatake YAMATO  */
parseGenericArgs(rSubparser * s,tokenInfo * const token,int parent,tokenInfo * const open_paren)2311ce09ad9SMasatake YAMATO static bool parseGenericArgs (rSubparser *s, tokenInfo *const token, int parent,
2321ce09ad9SMasatake YAMATO 							  tokenInfo *const open_paren)
2331ce09ad9SMasatake YAMATO {
23419bff7a2SMasatake YAMATO 	while (!tokenIsTypeVal (token, ')'))
2351ce09ad9SMasatake YAMATO 	{
23619bff7a2SMasatake YAMATO 		if (!rParseStatement (token, parent, true))
23719bff7a2SMasatake YAMATO 			break;
23819bff7a2SMasatake YAMATO 		else if (tokenIsTypeVal (token, '\n'))
2391ce09ad9SMasatake YAMATO 			rTokenReadNoNewline (token);
2401ce09ad9SMasatake YAMATO 	}
2411ce09ad9SMasatake YAMATO 	return false;
2421ce09ad9SMasatake YAMATO }
2431ce09ad9SMasatake YAMATO 
2441ce09ad9SMasatake YAMATO /* parse
2451ce09ad9SMasatake YAMATO  * this
2461ce09ad9SMasatake YAMATO  * area ---\          /--- parseArgs parses this area.
2471ce09ad9SMasatake YAMATO  *         V====VV----V
2481ce09ad9SMasatake YAMATO  *   setXXX("...", ...)
2491ce09ad9SMasatake YAMATO  */
parseSetCommon(rSubparser * s,tokenInfo * const token,int parent,int kind,bool (* parseArgs)(rSubparser *,tokenInfo * const,int,tokenInfo * const))2501ce09ad9SMasatake YAMATO static int parseSetCommon (rSubparser *s, tokenInfo *const token, int parent,
2511ce09ad9SMasatake YAMATO 						   int kind,
2521ce09ad9SMasatake YAMATO 						   bool (* parseArgs) (rSubparser *, tokenInfo *const, int, tokenInfo *const))
2531ce09ad9SMasatake YAMATO {
2541ce09ad9SMasatake YAMATO 	int q = CORK_NIL;
2551ce09ad9SMasatake YAMATO 	tokenInfo *const open_paren = newTokenByCopying (token);
2561ce09ad9SMasatake YAMATO 
2571ce09ad9SMasatake YAMATO 	rTokenReadNoNewline (token);
2581ce09ad9SMasatake YAMATO 	if (tokenIsType (token, R_STRING))
2591ce09ad9SMasatake YAMATO 	{
2601ce09ad9SMasatake YAMATO 		vString *n = rExtractNameFromString (token->string);
2611ce09ad9SMasatake YAMATO 		if (n)
2621ce09ad9SMasatake YAMATO 		{
2631ce09ad9SMasatake YAMATO 			q = makeSimpleTag (n, kind);
2641ce09ad9SMasatake YAMATO 			vStringDelete (n);
2651ce09ad9SMasatake YAMATO 		}
2661ce09ad9SMasatake YAMATO 	}
2671ce09ad9SMasatake YAMATO 
2681ce09ad9SMasatake YAMATO 	bool skip = true;
2691ce09ad9SMasatake YAMATO 	if (q != CORK_NIL && parseArgs)
2701ce09ad9SMasatake YAMATO 		skip = (* parseArgs) (s, token, q, open_paren);
2711ce09ad9SMasatake YAMATO 
2721ce09ad9SMasatake YAMATO 	if (skip)
2731ce09ad9SMasatake YAMATO 	{
2741ce09ad9SMasatake YAMATO 		tokenCopy (token, open_paren);
2751ce09ad9SMasatake YAMATO 		tokenSkipOverPair (token);
2761ce09ad9SMasatake YAMATO 	}
2771ce09ad9SMasatake YAMATO 
2781ce09ad9SMasatake YAMATO 	tokenDelete (open_paren);
2791ce09ad9SMasatake YAMATO 	return q;
2801ce09ad9SMasatake YAMATO }
2811ce09ad9SMasatake YAMATO 
parseSetClass(rSubparser * s,tokenInfo * const token,int parent)2821ce09ad9SMasatake YAMATO static int parseSetClass (rSubparser *s, tokenInfo *const token, int parent)
2831ce09ad9SMasatake YAMATO {
2841ce09ad9SMasatake YAMATO 	return parseSetCommon (s, token, parent, S4_K_CLASS, parseClassArgs);
2851ce09ad9SMasatake YAMATO }
2861ce09ad9SMasatake YAMATO 
parseSetGeneric(rSubparser * s,tokenInfo * const token,int parent)2871ce09ad9SMasatake YAMATO static int parseSetGeneric (rSubparser *s, tokenInfo *const token, int parent)
2881ce09ad9SMasatake YAMATO {
2891ce09ad9SMasatake YAMATO 	return parseSetCommon (s, token, parent, S4_K_GENERIC, parseGenericArgs);
2901ce09ad9SMasatake YAMATO }
2911ce09ad9SMasatake YAMATO 
parseSetMethod(rSubparser * s,tokenInfo * const token,int parent)2921ce09ad9SMasatake YAMATO static int parseSetMethod (rSubparser *s, tokenInfo *const token, int parent)
2931ce09ad9SMasatake YAMATO {
2941ce09ad9SMasatake YAMATO 	return parseSetCommon (s, token, parent, S4_K_METHOD, parseMethodArgs);
2951ce09ad9SMasatake YAMATO }
2961ce09ad9SMasatake YAMATO 
s4ReadFuncall(rSubparser * s,tokenInfo * const func,tokenInfo * const token,int parent)2971ce09ad9SMasatake YAMATO static int s4ReadFuncall (rSubparser *s,
2981ce09ad9SMasatake YAMATO 						  tokenInfo *const func, tokenInfo *const token,
2991ce09ad9SMasatake YAMATO 						  int parent)
3001ce09ad9SMasatake YAMATO {
3011ce09ad9SMasatake YAMATO 	if (strcmp (tokenString (func), "setClass") == 0)
3021ce09ad9SMasatake YAMATO 		return parseSetClass (s, token, parent);
3031ce09ad9SMasatake YAMATO 	else if (strcmp (tokenString (func), "setGeneric") == 0)
3041ce09ad9SMasatake YAMATO 		return parseSetGeneric (s, token, parent);
3051ce09ad9SMasatake YAMATO 	else if (strcmp (tokenString (func), "setMethod") == 0)
3061ce09ad9SMasatake YAMATO 		return parseSetMethod (s, token, parent);
3071ce09ad9SMasatake YAMATO 	else
3081ce09ad9SMasatake YAMATO 		return CORK_NIL;
3091ce09ad9SMasatake YAMATO }
3101ce09ad9SMasatake YAMATO 
s4AskTagAcceptancy(rSubparser * s,tagEntryInfo * pe)3111ce09ad9SMasatake YAMATO static bool s4AskTagAcceptancy (rSubparser *s, tagEntryInfo *pe)
3121ce09ad9SMasatake YAMATO {
3131ce09ad9SMasatake YAMATO 	return (pe->kindIndex == S4_K_CLASS);
3141ce09ad9SMasatake YAMATO }
3151ce09ad9SMasatake YAMATO 
s4HasFunctionAlikeKind(rSubparser * s,tagEntryInfo * e)316582f04dcSMasatake YAMATO static bool s4HasFunctionAlikeKind (rSubparser *s, tagEntryInfo *e)
317582f04dcSMasatake YAMATO {
318582f04dcSMasatake YAMATO 	return e->kindIndex == S4_K_METHOD ||
319582f04dcSMasatake YAMATO 		e->kindIndex == S4_K_GENERIC;
320582f04dcSMasatake YAMATO }
321582f04dcSMasatake YAMATO 
3221ce09ad9SMasatake YAMATO /*
3231ce09ad9SMasatake YAMATO  * setClass("class", representation(r0 = "t0", r1 = "t1", ...
3241ce09ad9SMasatake YAMATO  *
3251ce09ad9SMasatake YAMATO  * Attaching t as "typeref:typename:" field of r.
3261ce09ad9SMasatake YAMATO  *
3271ce09ad9SMasatake YAMATO  * the tag for "class" -> parent.
3281ce09ad9SMasatake YAMATO  * r0, r1, ... -> symbol
3291ce09ad9SMasatake YAMATO  */
s4ReadRightSideSymbol(rSubparser * s,tokenInfo * const symbol,const char * const assignmentOperator,int parent,tokenInfo * const token)3301ce09ad9SMasatake YAMATO static int s4ReadRightSideSymbol (rSubparser *s,
3311ce09ad9SMasatake YAMATO 								  tokenInfo *const symbol,
3321ce09ad9SMasatake YAMATO 								  const char *const assignmentOperator,
3331ce09ad9SMasatake YAMATO 								  int parent,
3341ce09ad9SMasatake YAMATO 								  tokenInfo *const token)
3351ce09ad9SMasatake YAMATO {
3361ce09ad9SMasatake YAMATO 	tagEntryInfo *pe = getEntryInCorkQueue (parent);
3371ce09ad9SMasatake YAMATO 	if (! (pe
3381ce09ad9SMasatake YAMATO 		   && pe->langType == s->subparser.slaveParser->id
3391ce09ad9SMasatake YAMATO 		   && pe->kindIndex == S4_K_CLASS))
3401ce09ad9SMasatake YAMATO 		return CORK_NIL;
3411ce09ad9SMasatake YAMATO 
3421ce09ad9SMasatake YAMATO 	tagEntryInfo e;
3431ce09ad9SMasatake YAMATO 	int q;
3441ce09ad9SMasatake YAMATO 	vString *t = NULL;
3451ce09ad9SMasatake YAMATO 
3461ce09ad9SMasatake YAMATO 	if (tokenIsType (token, R_STRING))
3471ce09ad9SMasatake YAMATO 		t = rExtractNameFromString (token->string);
3481ce09ad9SMasatake YAMATO 
3491ce09ad9SMasatake YAMATO 	initTagEntry (&e, tokenString (symbol), S4_K_REPRESENTATION);
3501ce09ad9SMasatake YAMATO 	e.extensionFields.scopeIndex = parent;
3511ce09ad9SMasatake YAMATO 	if (t)
3521ce09ad9SMasatake YAMATO 	{
3531ce09ad9SMasatake YAMATO 		e.extensionFields.typeRef[0] = "typename";
3541ce09ad9SMasatake YAMATO 		e.extensionFields.typeRef[1] = vStringValue (t);
3551ce09ad9SMasatake YAMATO 	}
3561ce09ad9SMasatake YAMATO 	q = makeTagEntry (&e);
3571ce09ad9SMasatake YAMATO 	vStringDelete (t);			/* NULL is acceptable. */
3581ce09ad9SMasatake YAMATO 
3591ce09ad9SMasatake YAMATO 	return q;
3601ce09ad9SMasatake YAMATO }
3611ce09ad9SMasatake YAMATO 
findS4Tags(void)3621ce09ad9SMasatake YAMATO static void findS4Tags(void)
3631ce09ad9SMasatake YAMATO {
3641ce09ad9SMasatake YAMATO 	scheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);
3651ce09ad9SMasatake YAMATO }
3661ce09ad9SMasatake YAMATO 
S4ClassParser(void)3671ce09ad9SMasatake YAMATO extern parserDefinition* S4ClassParser (void)
3681ce09ad9SMasatake YAMATO {
3691ce09ad9SMasatake YAMATO 	parserDefinition* const def = parserNew("S4Class");
3701ce09ad9SMasatake YAMATO 
3711ce09ad9SMasatake YAMATO 	static parserDependency dependencies [] = {
3721ce09ad9SMasatake YAMATO 		[0] = { DEPTYPE_SUBPARSER, "R", &s4Subparser },
3731ce09ad9SMasatake YAMATO 	};
3741ce09ad9SMasatake YAMATO 
3751ce09ad9SMasatake YAMATO 	def->dependencies = dependencies;
3761ce09ad9SMasatake YAMATO 	def->dependencyCount = ARRAY_SIZE (dependencies);
3771ce09ad9SMasatake YAMATO 
3781ce09ad9SMasatake YAMATO 	def->kindTable = S4Kinds;
3791ce09ad9SMasatake YAMATO 	def->kindCount = ARRAY_SIZE(S4Kinds);
3801ce09ad9SMasatake YAMATO 
3811ce09ad9SMasatake YAMATO 	def->parser =  findS4Tags;
3821ce09ad9SMasatake YAMATO 	def->useCork = CORK_QUEUE;
3831ce09ad9SMasatake YAMATO 
3841ce09ad9SMasatake YAMATO 	return def;
3851ce09ad9SMasatake YAMATO }
386