xref: /Universal-ctags/parsers/r.c (revision aaaac7eeac8399141aa8e6d9e6ec0379931848b2)
1ade07043SVitor Antunes /*
2ade07043SVitor Antunes *   Copyright (c) 2003-2004, Ascher Stefan <stievie@utanet.at>
325ec6aefSMasatake YAMATO *   Copyright (c) 2020, Masatake YAMATO <yamato@redhat.com>
425ec6aefSMasatake YAMATO *   Copyright (c) 2020, Red Hat, Inc.
5ade07043SVitor Antunes *
6ade07043SVitor Antunes *   This source code is released for free distribution under the terms of the
70ce38835Sviccuad *   GNU General Public License version 2 or (at your option) any later version.
8ade07043SVitor Antunes *
9ade07043SVitor Antunes *   This module contains functions for generating tags for R language files.
10ade07043SVitor Antunes *   R is a programming language for statistical computing.
11ade07043SVitor Antunes *   R is GPL Software, get it from http://www.r-project.org/
1225ec6aefSMasatake YAMATO *
1325ec6aefSMasatake YAMATO *   The language references are available at
1425ec6aefSMasatake YAMATO *   https://cran.r-project.org/manuals.html, and
1525ec6aefSMasatake YAMATO *   https://cran.r-project.org/doc/manuals/r-release/R-lang.html
160c4eabdcSMasatake YAMATO *
17433f2215SMasanari Iida *   The base library (including library and source functions) release is at
180c4eabdcSMasatake YAMATO *   https://stat.ethz.ch/R-manual/R-devel/library/base/html/00Index.html
19ade07043SVitor Antunes */
20ade07043SVitor Antunes 
21ade07043SVitor Antunes /*
22ade07043SVitor Antunes *   INCLUDE FILES
23ade07043SVitor Antunes */
24ade07043SVitor Antunes #include "general.h"	/* must always come first */
25ade07043SVitor Antunes 
26ade07043SVitor Antunes #include "debug.h"
27ade07043SVitor Antunes #include "entry.h"
2825ec6aefSMasatake YAMATO #include "keyword.h"
290d502ef0SMasatake YAMATO #include "parse.h"
30ade07043SVitor Antunes #include "read.h"
31ab3b3869SMasatake YAMATO #include "selectors.h"
3225ec6aefSMasatake YAMATO #include "tokeninfo.h"
3325ec6aefSMasatake YAMATO #include "trace.h"
34ade07043SVitor Antunes #include "vstring.h"
3530fa30b1SMasatake YAMATO #include "subparser.h"
3630fa30b1SMasatake YAMATO #include "r.h"
37ade07043SVitor Antunes 
3825ec6aefSMasatake YAMATO #include <string.h>
3925ec6aefSMasatake YAMATO #include <ctype.h>	/* to define isalpha(), isalnum(), isspace() */
4025ec6aefSMasatake YAMATO 
41629aa0ceSMasatake YAMATO 
4225ec6aefSMasatake YAMATO /*
4325ec6aefSMasatake YAMATO *   MACROS
4425ec6aefSMasatake YAMATO */
4525ec6aefSMasatake YAMATO #ifdef DEBUG
4625ec6aefSMasatake YAMATO #define R_TRACE_TOKEN_TEXT(TXT,T,Q) TRACE_PRINT("<%s> token: %s (%s), parent: %s", \
4725ec6aefSMasatake YAMATO 												(TXT),					\
4825ec6aefSMasatake YAMATO 												tokenIsTypeVal(T, '\n')? "\\n": tokenString(T), \
4925ec6aefSMasatake YAMATO 												tokenTypeStr(T->type),	\
5025ec6aefSMasatake YAMATO 												(Q) == CORK_NIL? "": getEntryInCorkQueue(Q)->name)
5125ec6aefSMasatake YAMATO #define R_TRACE_TOKEN(T,Q) TRACE_PRINT("token: %s (%s), parent: %s", \
5225ec6aefSMasatake YAMATO 									   tokenIsTypeVal((T), '\n')? "\\n": tokenString(T), \
5325ec6aefSMasatake YAMATO 									   tokenTypeStr((T)->type),			\
5425ec6aefSMasatake YAMATO 									   (Q) == CORK_NIL? "": getEntryInCorkQueue(Q)->name)
5525ec6aefSMasatake YAMATO 
5625ec6aefSMasatake YAMATO #define R_TRACE_ENTER() TRACE_ENTER_TEXT("token: %s (%s), parent: %s", \
5725ec6aefSMasatake YAMATO 										 tokenIsTypeVal(token, '\n')? "\\n": tokenString(token), \
5825ec6aefSMasatake YAMATO 										 tokenTypeStr(token->type), \
5925ec6aefSMasatake YAMATO 										 parent == CORK_NIL? "": getEntryInCorkQueue(parent)->name)
6025ec6aefSMasatake YAMATO #define R_TRACE_LEAVE() TRACE_LEAVE()
6125ec6aefSMasatake YAMATO #else
6225ec6aefSMasatake YAMATO #define R_TRACE_TOKEN_TEXT(TXT,T,Q) do {} while (0);
6325ec6aefSMasatake YAMATO #define R_TRACE_TOKEN(T,Q) do {} while (0);
6425ec6aefSMasatake YAMATO #define R_TRACE_ENTER() do {} while (0);
6525ec6aefSMasatake YAMATO #define R_TRACE_LEAVE() do {} while (0);
6625ec6aefSMasatake YAMATO #endif
6725ec6aefSMasatake YAMATO 
68629aa0ceSMasatake YAMATO 
6925ec6aefSMasatake YAMATO /*
7025ec6aefSMasatake YAMATO *   DATA DEFINITIONS
7125ec6aefSMasatake YAMATO */
72ade07043SVitor Antunes typedef enum {
7325ec6aefSMasatake YAMATO 	K_UNDEFINED = -1,
74ade07043SVitor Antunes 	K_FUNCTION,
75ade07043SVitor Antunes 	K_LIBRARY,
76ade07043SVitor Antunes 	K_SOURCE,
774c8039cfSVitor Antunes 	K_GLOBALVAR,
784c8039cfSVitor Antunes 	K_FUNCVAR,
7925ec6aefSMasatake YAMATO 	K_PARAM,
80cd905678SMasatake YAMATO 	K_VECTOR,
812b000035SMasatake YAMATO 	K_LIST,
8209bc94cdSMasatake YAMATO 	K_DATAFRAME,
83cd905678SMasatake YAMATO 	K_NAMEATTR,
84ade07043SVitor Antunes 	KIND_COUNT
85ade07043SVitor Antunes } rKind;
86ade07043SVitor Antunes 
870c4eabdcSMasatake YAMATO typedef enum {
880c4eabdcSMasatake YAMATO 	R_LIBRARY_ATTACHED_BY_LIBRARY,
890c4eabdcSMasatake YAMATO 	R_LIBRARY_ATTACHED_BY_REQUIRE,
900c4eabdcSMasatake YAMATO } rLibraryRole;
910c4eabdcSMasatake YAMATO 
920c4eabdcSMasatake YAMATO typedef enum {
930c4eabdcSMasatake YAMATO 	R_SOURCE_LOADED_BY_SOURCE,
940c4eabdcSMasatake YAMATO } rSourceRole;
950c4eabdcSMasatake YAMATO 
960c4eabdcSMasatake YAMATO static roleDefinition RLibraryRoles [] = {
97433f2215SMasanari Iida 	{ true, "library", "library attached by library function" },
98433f2215SMasanari Iida 	{ true, "require", "library attached by require function" },
990c4eabdcSMasatake YAMATO };
1000c4eabdcSMasatake YAMATO 
1010c4eabdcSMasatake YAMATO static roleDefinition RSourceRoles [] = {
1020c4eabdcSMasatake YAMATO 	{ true, "source", "source loaded by source fucntion" },
1030c4eabdcSMasatake YAMATO };
1040c4eabdcSMasatake YAMATO 
105e112e8abSMasatake YAMATO static kindDefinition RKinds[KIND_COUNT] = {
106ce990805SThomas Braun 	{true, 'f', "function", "functions"},
1070c4eabdcSMasatake YAMATO 	{true, 'l', "library", "libraries",
1080c4eabdcSMasatake YAMATO 	 .referenceOnly = true, ATTACH_ROLES (RLibraryRoles) },
1090c4eabdcSMasatake YAMATO 	{true, 's', "source", "sources",
1100c4eabdcSMasatake YAMATO 	 .referenceOnly = true, ATTACH_ROLES (RSourceRoles) },
111bd0d90a5SMasatake YAMATO 	{true, 'g', "globalVar", "global variables having values other than function()"},
112bd0d90a5SMasatake YAMATO 	{true, 'v', "functionVar", "function variables having values other than function()"},
11325ec6aefSMasatake YAMATO 	{false,'z', "parameter",  "function parameters inside function definitions" },
114cd905678SMasatake YAMATO 	{true, 'c', "vector", "vectors explicitly created with `c()'" },
1152b000035SMasatake YAMATO 	{true, 'L', "list", "lists explicitly created with `list()'" },
11609bc94cdSMasatake YAMATO 	{true, 'd', "dataframe", "data frame explicitly created with `data.frame()'" },
11709bc94cdSMasatake YAMATO 	{true, 'n', "nameattr", "names attribtes in vectors, lists, or dataframes" },
118ade07043SVitor Antunes };
119ade07043SVitor Antunes 
1207fa0953aSMasatake YAMATO struct sKindExtraInfo {
1217fa0953aSMasatake YAMATO 	const char *anon_prefix;
1227fa0953aSMasatake YAMATO 	const char *ctor;
1237fa0953aSMasatake YAMATO };
1247fa0953aSMasatake YAMATO 
1257fa0953aSMasatake YAMATO static struct sKindExtraInfo kindExtraInfo[KIND_COUNT] = {
1267fa0953aSMasatake YAMATO 	[K_FUNCTION] = {
1277fa0953aSMasatake YAMATO 		"anonFunc",
1287fa0953aSMasatake YAMATO 		"function",
1297fa0953aSMasatake YAMATO 	},
130cd905678SMasatake YAMATO 	[K_VECTOR] = {
131cd905678SMasatake YAMATO 		"anonVec",
132cd905678SMasatake YAMATO 		"c",
133cd905678SMasatake YAMATO 	},
1342b000035SMasatake YAMATO 	[K_LIST] = {
1352b000035SMasatake YAMATO 		"anonList",
1362b000035SMasatake YAMATO 		"list",
1372b000035SMasatake YAMATO 	},
13809bc94cdSMasatake YAMATO 	[K_DATAFRAME] = {
13909bc94cdSMasatake YAMATO 		"anonDataFrame",
14009bc94cdSMasatake YAMATO 		"data.frame",
14109bc94cdSMasatake YAMATO 	},
1427fa0953aSMasatake YAMATO };
1437fa0953aSMasatake YAMATO 
14425ec6aefSMasatake YAMATO typedef enum {
14525ec6aefSMasatake YAMATO 	F_ASSIGNMENT_OPERATOR,
146036b5019SMasatake YAMATO 	F_CONSTRUCTOR,
14725ec6aefSMasatake YAMATO } rField;
148ade07043SVitor Antunes 
14925ec6aefSMasatake YAMATO static fieldDefinition RFields [] = {
15025ec6aefSMasatake YAMATO 	{
15125ec6aefSMasatake YAMATO 		.name = "assignmentop",
15225ec6aefSMasatake YAMATO 		.description = "operator for assignment",
15325ec6aefSMasatake YAMATO 		.enabled = false,
15425ec6aefSMasatake YAMATO 	},
155036b5019SMasatake YAMATO 	{
156036b5019SMasatake YAMATO 		.name = "constructor",
157cd905678SMasatake YAMATO 		.description = "function used for making value assigned to the nameattr tag",
158036b5019SMasatake YAMATO 		.enabled = true,
159036b5019SMasatake YAMATO 	}
16025ec6aefSMasatake YAMATO };
161ade07043SVitor Antunes 
16225ec6aefSMasatake YAMATO typedef int keywordId;			/* to allow KEYWORD_NONE */
163ade07043SVitor Antunes 
16425ec6aefSMasatake YAMATO static const keywordTable RKeywordTable [] = {
165cd905678SMasatake YAMATO 	{ "c",        KEYWORD_R_C        },
1662b000035SMasatake YAMATO 	{ "list",     KEYWORD_R_LIST     },
16709bc94cdSMasatake YAMATO 	{ "data.frame",KEYWORD_R_DATAFRAME },
16830fa30b1SMasatake YAMATO 	{ "function", KEYWORD_R_FUNCTION },
16930fa30b1SMasatake YAMATO 	{ "if",       KEYWORD_R_IF       },
17030fa30b1SMasatake YAMATO 	{ "else",     KEYWORD_R_ELSE     },
17130fa30b1SMasatake YAMATO 	{ "for",      KEYWORD_R_FOR      },
17230fa30b1SMasatake YAMATO 	{ "while",    KEYWORD_R_WHILE    },
17330fa30b1SMasatake YAMATO 	{ "repeat",   KEYWORD_R_REPEAT   },
17430fa30b1SMasatake YAMATO 	{ "in",       KEYWORD_R_IN       },
17530fa30b1SMasatake YAMATO 	{ "next",     KEYWORD_R_NEXT     },
17630fa30b1SMasatake YAMATO 	{ "break",    KEYWORD_R_BREAK    },
17730fa30b1SMasatake YAMATO 	{ "TRUE",     KEYWORD_R_TRUE,    },
17830fa30b1SMasatake YAMATO 	{ "FALSE",    KEYWORD_R_FALSE,   },
17930fa30b1SMasatake YAMATO 	{ "NULL",     KEYWORD_R_NULL,    },
18030fa30b1SMasatake YAMATO 	{ "Inf",      KEYWORD_R_INF,     },
18130fa30b1SMasatake YAMATO 	{ "NaN",      KEYWORD_R_NAN,     },
18230fa30b1SMasatake YAMATO 	{ "NA",       KEYWORD_R_NA,      },
18330fa30b1SMasatake YAMATO 	{ "NA_integer_",   KEYWORD_R_NA, },
18430fa30b1SMasatake YAMATO 	{ "NA_real_",      KEYWORD_R_NA, },
18530fa30b1SMasatake YAMATO 	{ "NA_complex_",   KEYWORD_R_NA, },
18630fa30b1SMasatake YAMATO 	{ "NA_character_", KEYWORD_R_NA, },
18730fa30b1SMasatake YAMATO 	{ "source",   KEYWORD_R_SOURCE   },
18830fa30b1SMasatake YAMATO 	{ "library",  KEYWORD_R_LIBRARY  },
18930fa30b1SMasatake YAMATO 	{ "require",  KEYWORD_R_LIBRARY  },
19025ec6aefSMasatake YAMATO };
191ade07043SVitor Antunes 
19225ec6aefSMasatake YAMATO #ifdef DEBUG
19325ec6aefSMasatake YAMATO static const char *tokenTypeStr(enum RTokenType e);
19425ec6aefSMasatake YAMATO #endif
195ade07043SVitor Antunes 
19625ec6aefSMasatake YAMATO static struct tokenTypePair typePairs [] = {
19725ec6aefSMasatake YAMATO 	{ '{', '}' },
19825ec6aefSMasatake YAMATO 	{ '[', ']' },
19925ec6aefSMasatake YAMATO 	{ '(', ')' },
20025ec6aefSMasatake YAMATO };
201ade07043SVitor Antunes 
20225ec6aefSMasatake YAMATO typedef struct sRToken {
20325ec6aefSMasatake YAMATO 	tokenInfo base;
20425ec6aefSMasatake YAMATO 	int scopeIndex;
20525ec6aefSMasatake YAMATO 	int parenDepth;
20625ec6aefSMasatake YAMATO 	vString *signature;
207c1117bc9SMasatake YAMATO 	int kindIndexForParams;		/* Used only when gathering parameters */
20825ec6aefSMasatake YAMATO } rToken;
209ade07043SVitor Antunes 
21025ec6aefSMasatake YAMATO #define R(TOKEN) ((rToken *)TOKEN)
211ade07043SVitor Antunes 
212ed1b6f16SMasatake YAMATO static int blackHoleIndex;
213ed1b6f16SMasatake YAMATO 
21430fa30b1SMasatake YAMATO static langType Lang_R;
21530fa30b1SMasatake YAMATO 
21625ec6aefSMasatake YAMATO static void readToken (tokenInfo *const token, void *data);
21725ec6aefSMasatake YAMATO static void clearToken (tokenInfo *token);
21825ec6aefSMasatake YAMATO static struct tokenInfoClass rTokenInfoClass = {
21925ec6aefSMasatake YAMATO 	.nPreAlloc        = 4,
22030fa30b1SMasatake YAMATO 	.typeForUndefined = TOKEN_R_UNDEFINED,
22125ec6aefSMasatake YAMATO 	.keywordNone      = KEYWORD_NONE,
22230fa30b1SMasatake YAMATO 	.typeForKeyword   = TOKEN_R_KEYWORD,
22330fa30b1SMasatake YAMATO 	.typeForEOF       = TOKEN_R_EOF,
22425ec6aefSMasatake YAMATO 	.extraSpace       = sizeof (rToken) - sizeof (tokenInfo),
22525ec6aefSMasatake YAMATO 	.pairs            = typePairs,
22625ec6aefSMasatake YAMATO 	.pairCount        = ARRAY_SIZE (typePairs),
22725ec6aefSMasatake YAMATO 	.init             = NULL,
22825ec6aefSMasatake YAMATO 	.read             = readToken,
22925ec6aefSMasatake YAMATO 	.clear            = clearToken,
23025ec6aefSMasatake YAMATO 	.copy             = NULL,
23125ec6aefSMasatake YAMATO };
23225ec6aefSMasatake YAMATO 
23325ec6aefSMasatake YAMATO 
23425ec6aefSMasatake YAMATO /*
23525ec6aefSMasatake YAMATO  * FUNCTION PROTOTYPES
236ade07043SVitor Antunes  */
237acc50dcaSMasatake YAMATO static bool parseStatement (tokenInfo *const token, int parent, bool in_arglist, bool in_continuous_pair);
2380c4eabdcSMasatake YAMATO static void parsePair (tokenInfo *const token, int parent, tokenInfo *const funcall);
23925ec6aefSMasatake YAMATO 
24030fa30b1SMasatake YAMATO static  int notifyReadRightSideSymbol (tokenInfo *const symbol,
24130fa30b1SMasatake YAMATO 									   const char *const assignmentOperator,
24230fa30b1SMasatake YAMATO 									   int parent,
24330fa30b1SMasatake YAMATO 									   tokenInfo *const token);
24430fa30b1SMasatake YAMATO static  int makeSimpleSubparserTag (int langType, tokenInfo *const token, int parent,
24530fa30b1SMasatake YAMATO 									bool in_func, int kindInR, const char *assignmentOperator);
24630fa30b1SMasatake YAMATO static  bool askSubparserTagAcceptancy (tagEntryInfo *pe);
247bd0d90a5SMasatake YAMATO static  bool askSubparserTagHasFunctionAlikeKind (tagEntryInfo *e);
248d1586adcSMasatake YAMATO static  int notifyReadFuncall (tokenInfo *const func, tokenInfo *const token, int parent);
24925ec6aefSMasatake YAMATO 
25025ec6aefSMasatake YAMATO /*
25125ec6aefSMasatake YAMATO *   FUNCTION DEFINITIONS
25225ec6aefSMasatake YAMATO */
hasKindsOrCtors(tagEntryInfo * e,int kinds[],size_t count)253c22fe5fbSMasatake YAMATO static bool hasKindsOrCtors (tagEntryInfo * e, int kinds[], size_t count)
25435b90ec9SMasatake YAMATO {
25535b90ec9SMasatake YAMATO        if (e->langType == Lang_R)
25635b90ec9SMasatake YAMATO 	   {
257c22fe5fbSMasatake YAMATO 		   for (size_t i = 0; i < count; i++)
258c22fe5fbSMasatake YAMATO 		   {
259c22fe5fbSMasatake YAMATO 			   if (e->kindIndex == kinds[i])
26035b90ec9SMasatake YAMATO 				   return true;
26135b90ec9SMasatake YAMATO 		   }
262c22fe5fbSMasatake YAMATO 	   }
263c22fe5fbSMasatake YAMATO 	   else
26435b90ec9SMasatake YAMATO 	   {
265c22fe5fbSMasatake YAMATO 		   bool function = false;
266c22fe5fbSMasatake YAMATO 		   for (size_t i = 0; i < count; i++)
267c22fe5fbSMasatake YAMATO 		   {
268c22fe5fbSMasatake YAMATO 			   if (K_FUNCTION == kinds[i])
269c22fe5fbSMasatake YAMATO 			   {
270c22fe5fbSMasatake YAMATO 				   function = true;
271c22fe5fbSMasatake YAMATO 				   break;
272c22fe5fbSMasatake YAMATO 			   }
273c22fe5fbSMasatake YAMATO 		   }
274c22fe5fbSMasatake YAMATO 		   if (function && askSubparserTagHasFunctionAlikeKind (e))
27535b90ec9SMasatake YAMATO 			   return true;
27635b90ec9SMasatake YAMATO 	   }
27735b90ec9SMasatake YAMATO 
27835b90ec9SMasatake YAMATO 	   const char *tmp = getParserFieldValueForType (e,
27935b90ec9SMasatake YAMATO 													 RFields [F_CONSTRUCTOR].ftype);
28035b90ec9SMasatake YAMATO 	   if (tmp == NULL)
28135b90ec9SMasatake YAMATO 		   return false;
28235b90ec9SMasatake YAMATO 
283c22fe5fbSMasatake YAMATO 	   for (size_t i = 0; i < count; i++)
284c22fe5fbSMasatake YAMATO 	   {
285c22fe5fbSMasatake YAMATO 		   const char * ctor = kindExtraInfo [kinds[i]].ctor;
286c22fe5fbSMasatake YAMATO 		   if (ctor && strcmp (tmp, ctor) == 0)
28735b90ec9SMasatake YAMATO                return true;
288c22fe5fbSMasatake YAMATO 	   }
28935b90ec9SMasatake YAMATO 
29035b90ec9SMasatake YAMATO        return false;
29135b90ec9SMasatake YAMATO }
29235b90ec9SMasatake YAMATO 
searchScopeOtherThan(int scope,int kinds[],size_t count)293c22fe5fbSMasatake YAMATO static int searchScopeOtherThan (int scope, int kinds[], size_t count)
294cd905678SMasatake YAMATO {
295cd905678SMasatake YAMATO 	do
296cd905678SMasatake YAMATO 	{
297cd905678SMasatake YAMATO 		tagEntryInfo * e = getEntryInCorkQueue (scope);
298cd905678SMasatake YAMATO 		if (!e)
299cd905678SMasatake YAMATO 			return CORK_NIL;
300cd905678SMasatake YAMATO 
301c22fe5fbSMasatake YAMATO 		if (!hasKindsOrCtors (e, kinds, count))
302cd905678SMasatake YAMATO 			return scope;
303cd905678SMasatake YAMATO 
304cd905678SMasatake YAMATO 		scope = e->extensionFields.scopeIndex;
305cd905678SMasatake YAMATO 	}
306cd905678SMasatake YAMATO 	while (1);
307cd905678SMasatake YAMATO }
308cd905678SMasatake YAMATO 
makeSimpleRTagR(tokenInfo * const token,int parent,int kind,const char * assignmentOp)30930fa30b1SMasatake YAMATO static int makeSimpleRTagR (tokenInfo *const token, int parent, int kind,
31081a07fd2SMasatake YAMATO 							const char * assignmentOp)
311ed1b6f16SMasatake YAMATO {
31281a07fd2SMasatake YAMATO 	if (assignmentOp && (strlen (assignmentOp) == 3))
31381a07fd2SMasatake YAMATO 	{
31481a07fd2SMasatake YAMATO 		/* <<- or ->> is used here. */
31581a07fd2SMasatake YAMATO 		if (anyKindsEntryInScopeRecursive (parent, tokenString (token),
31681a07fd2SMasatake YAMATO 										   (int[]){K_FUNCTION,
31781a07fd2SMasatake YAMATO 												   K_GLOBALVAR,
31881a07fd2SMasatake YAMATO 												   K_FUNCVAR,
319*aaaac7eeSMasatake YAMATO 												   K_PARAM}, 4,
320*aaaac7eeSMasatake YAMATO 										   false) != CORK_NIL)
32181a07fd2SMasatake YAMATO 			return CORK_NIL;
32281a07fd2SMasatake YAMATO 
32381a07fd2SMasatake YAMATO 		parent = CORK_NIL;
32481a07fd2SMasatake YAMATO 	}
325bd0d90a5SMasatake YAMATO 
326bd0d90a5SMasatake YAMATO 	/* If the tag (T) to be created is defined in a scope and
327bd0d90a5SMasatake YAMATO 	   the scope already has another tag having the same name
328bd0d90a5SMasatake YAMATO 	   as T, T should not be created. */
329bd0d90a5SMasatake YAMATO 	tagEntryInfo *pe = getEntryInCorkQueue (parent);
330bd0d90a5SMasatake YAMATO 	int cousin = CORK_NIL;
331bd0d90a5SMasatake YAMATO 	if (pe && ((pe->langType == Lang_R && pe->kindIndex == K_FUNCTION)
332bd0d90a5SMasatake YAMATO 			   || (pe->langType != Lang_R && askSubparserTagHasFunctionAlikeKind (pe))))
333ed1b6f16SMasatake YAMATO 	{
334*aaaac7eeSMasatake YAMATO 		cousin = anyEntryInScope (parent, tokenString (token), false);
335bd0d90a5SMasatake YAMATO 		if (kind == K_GLOBALVAR)
336bd0d90a5SMasatake YAMATO 			kind = K_FUNCVAR;
337bd0d90a5SMasatake YAMATO 	}
3382b000035SMasatake YAMATO 	else if (pe && (kind == K_GLOBALVAR)
33909bc94cdSMasatake YAMATO 			 && hasKindsOrCtors (pe, (int[]){K_VECTOR, K_LIST, K_DATAFRAME}, 3))
340cd905678SMasatake YAMATO 	{
341cd905678SMasatake YAMATO 		parent = searchScopeOtherThan (pe->extensionFields.scopeIndex,
34209bc94cdSMasatake YAMATO 									   (int[]){K_VECTOR, K_LIST, K_DATAFRAME}, 3);
343cd905678SMasatake YAMATO 		if (parent == CORK_NIL)
344*aaaac7eeSMasatake YAMATO 			cousin = anyKindEntryInScope (parent, tokenString (token), K_GLOBALVAR, false);
345cd905678SMasatake YAMATO 		else
346cd905678SMasatake YAMATO 		{
347*aaaac7eeSMasatake YAMATO 			cousin = anyKindEntryInScope (parent, tokenString (token), K_FUNCVAR, false);
348cd905678SMasatake YAMATO 			kind = K_FUNCVAR;
349cd905678SMasatake YAMATO 		}
350cd905678SMasatake YAMATO 	}
351bd0d90a5SMasatake YAMATO 	else if (pe)
352ed1b6f16SMasatake YAMATO 	{
353bd0d90a5SMasatake YAMATO 		/* The condition for tagging is a bit relaxed here.
354bd0d90a5SMasatake YAMATO 		   Even if the same name tag is created in the scope, a name
355bd0d90a5SMasatake YAMATO 		   is tagged if kinds are different. */
356*aaaac7eeSMasatake YAMATO 		cousin = anyKindEntryInScope (parent, tokenString (token), kind, false);
357ed1b6f16SMasatake YAMATO 	}
358bd0d90a5SMasatake YAMATO 	if (cousin != CORK_NIL)
359ed1b6f16SMasatake YAMATO 		return CORK_NIL;
360ed1b6f16SMasatake YAMATO 
361ed1b6f16SMasatake YAMATO 	int corkIndex = makeSimpleTag (token->string, kind);
362ed1b6f16SMasatake YAMATO 	tagEntryInfo *tag = getEntryInCorkQueue (corkIndex);
363ed1b6f16SMasatake YAMATO 	if (tag)
364ed1b6f16SMasatake YAMATO 	{
365ed1b6f16SMasatake YAMATO 		tag->extensionFields.scopeIndex = parent;
36681a07fd2SMasatake YAMATO 		if (assignmentOp)
367ee670097SMasatake YAMATO 		{
368ee670097SMasatake YAMATO 			if (strlen (assignmentOp) > 0)
36981a07fd2SMasatake YAMATO 				attachParserField (tag, true,
37081a07fd2SMasatake YAMATO 								   RFields [F_ASSIGNMENT_OPERATOR].ftype,
37181a07fd2SMasatake YAMATO 								   assignmentOp);
372ee670097SMasatake YAMATO 			else
373ee670097SMasatake YAMATO 				markTagExtraBit (tag, XTAG_ANONYMOUS);
374ee670097SMasatake YAMATO 		}
375ed1b6f16SMasatake YAMATO 		registerEntry (corkIndex);
376ed1b6f16SMasatake YAMATO 	}
377ed1b6f16SMasatake YAMATO 	return corkIndex;
378ed1b6f16SMasatake YAMATO }
379ed1b6f16SMasatake YAMATO 
makeSimpleRTag(tokenInfo * const token,int parent,bool in_func,int kind,const char * assignmentOp)38030fa30b1SMasatake YAMATO static int makeSimpleRTag (tokenInfo *const token, int parent, bool in_func, int kind,
38130fa30b1SMasatake YAMATO 						   const char * assignmentOp)
38230fa30b1SMasatake YAMATO {
38335b90ec9SMasatake YAMATO 	int r;
38435b90ec9SMasatake YAMATO 	const char *ctor = kindExtraInfo [kind].ctor;
38530fa30b1SMasatake YAMATO 	tagEntryInfo *pe = (parent == CORK_NIL)? NULL: getEntryInCorkQueue (parent);
38635b90ec9SMasatake YAMATO 
387cd905678SMasatake YAMATO 	/* makeTagWithTranslation method for subparsers
388cd905678SMasatake YAMATO 	   called from makeSimpleSubparserTag expects
389cd905678SMasatake YAMATO 	   kind should be resolved. */
39009bc94cdSMasatake YAMATO 	if (pe && hasKindsOrCtors (pe, (int[]){K_VECTOR, K_LIST, K_DATAFRAME}, 3))
391cd905678SMasatake YAMATO 	{
392cd905678SMasatake YAMATO 		if (assignmentOp
393cd905678SMasatake YAMATO 			&& strcmp (assignmentOp, "=") == 0)
394cd905678SMasatake YAMATO 			kind = K_NAMEATTR;
395cd905678SMasatake YAMATO 	}
396cd905678SMasatake YAMATO 
39780da9c4cSMasatake YAMATO 	bool foreign_tag = false;
39830fa30b1SMasatake YAMATO 	if (pe == NULL || pe->langType == Lang_R ||
39930fa30b1SMasatake YAMATO 		!askSubparserTagAcceptancy (pe))
40035b90ec9SMasatake YAMATO 		r = makeSimpleRTagR (token, parent, kind, assignmentOp);
40130fa30b1SMasatake YAMATO 	else
40280da9c4cSMasatake YAMATO 	{
40380da9c4cSMasatake YAMATO 		foreign_tag = true;
40435b90ec9SMasatake YAMATO 		r = makeSimpleSubparserTag (pe->langType, token, parent, in_func,
40530fa30b1SMasatake YAMATO 									kind, assignmentOp);
40680da9c4cSMasatake YAMATO 	}
40735b90ec9SMasatake YAMATO 
40880da9c4cSMasatake YAMATO 	if ((kind == K_NAMEATTR || foreign_tag) && ctor)
40935b90ec9SMasatake YAMATO 	{
41035b90ec9SMasatake YAMATO 		tagEntryInfo *e = getEntryInCorkQueue (r);
41135b90ec9SMasatake YAMATO 		if (e)
41235b90ec9SMasatake YAMATO 			attachParserField (e, true,
41335b90ec9SMasatake YAMATO 							   RFields [F_CONSTRUCTOR].ftype,
41435b90ec9SMasatake YAMATO 							   ctor);
41535b90ec9SMasatake YAMATO 	}
41635b90ec9SMasatake YAMATO 
41735b90ec9SMasatake YAMATO 	return r;
41830fa30b1SMasatake YAMATO }
41930fa30b1SMasatake YAMATO 
clearToken(tokenInfo * token)42025ec6aefSMasatake YAMATO static void clearToken (tokenInfo *token)
421e8b3358eSVitor Antunes {
42225ec6aefSMasatake YAMATO 	R (token)->parenDepth = 0;
42325ec6aefSMasatake YAMATO 	R (token)->scopeIndex = CORK_NIL;
424c1117bc9SMasatake YAMATO 	R (token)->kindIndexForParams = KIND_GHOST_INDEX;
42525ec6aefSMasatake YAMATO 	if (R (token)->signature)
42625ec6aefSMasatake YAMATO 	{
42725ec6aefSMasatake YAMATO 		vStringDelete (R (token)->signature);
42825ec6aefSMasatake YAMATO 		R (token)->signature = NULL;
429ade07043SVitor Antunes 	}
430ade07043SVitor Antunes }
431ade07043SVitor Antunes 
readString(tokenInfo * const token,void * data)43225ec6aefSMasatake YAMATO static void readString (tokenInfo *const token, void *data)
433e8b3358eSVitor Antunes {
43425ec6aefSMasatake YAMATO 	int c;
43525ec6aefSMasatake YAMATO 	bool escaped = false;
436ade07043SVitor Antunes 
43725ec6aefSMasatake YAMATO 	int c0 = tokenString(token)[0];
4384c8039cfSVitor Antunes 
43925ec6aefSMasatake YAMATO 	while (1)
44025ec6aefSMasatake YAMATO 	{
44125ec6aefSMasatake YAMATO 		c = getcFromInputFile ();
44225ec6aefSMasatake YAMATO 		switch (c)
44325ec6aefSMasatake YAMATO 		{
44425ec6aefSMasatake YAMATO 		case EOF:
44525ec6aefSMasatake YAMATO 			return;
44625ec6aefSMasatake YAMATO 		case '\'':
44725ec6aefSMasatake YAMATO 		case '"':
44825ec6aefSMasatake YAMATO 		case '`':
44925ec6aefSMasatake YAMATO 			tokenPutc (token, c);
45025ec6aefSMasatake YAMATO 			if (!escaped && c == c0)
45125ec6aefSMasatake YAMATO 				return;
45225ec6aefSMasatake YAMATO 			escaped = false;
4534c8039cfSVitor Antunes 			break;
45425ec6aefSMasatake YAMATO 		case '\\':
45525ec6aefSMasatake YAMATO 			tokenPutc (token, c);
45625ec6aefSMasatake YAMATO 			escaped = !escaped;
457ade07043SVitor Antunes 			break;
458ade07043SVitor Antunes 		default:
45925ec6aefSMasatake YAMATO 			tokenPutc (token, c);
46025ec6aefSMasatake YAMATO 			escaped = false;
461ade07043SVitor Antunes 			break;
462ade07043SVitor Antunes 		}
463ade07043SVitor Antunes 	}
464ade07043SVitor Antunes }
465ade07043SVitor Antunes 
readNumber(tokenInfo * const token,void * data)46625ec6aefSMasatake YAMATO static void readNumber (tokenInfo *const token, void *data)
46725ec6aefSMasatake YAMATO {
46825ec6aefSMasatake YAMATO 	int c;
46925ec6aefSMasatake YAMATO 
47025ec6aefSMasatake YAMATO 	/* 10.3.1 Constants
47125ec6aefSMasatake YAMATO 	 *
47225ec6aefSMasatake YAMATO 	 * Valid numeric constants: 1 10 0.1 .2 1e-7 1.2e+7
47325ec6aefSMasatake YAMATO 	 * Valid integer constants:  1L, 0x10L, 1000000L, 1e6L
47425ec6aefSMasatake YAMATO 	 * Valid numeric constants:  1.1L, 1e-3L, 0x1.1p-2
47525ec6aefSMasatake YAMATO 	 * Valid complex constants: 2i 4.1i 1e-2i
47625ec6aefSMasatake YAMATO 	 */
47725ec6aefSMasatake YAMATO 	while ((c = getcFromInputFile ()))
47825ec6aefSMasatake YAMATO 	{
47925ec6aefSMasatake YAMATO 		if (isxdigit (c) || c == '.' || c == 'E'
48025ec6aefSMasatake YAMATO 			|| c == '+' || c == '-'
48125ec6aefSMasatake YAMATO 			|| c == 'L' || c == 'x' || c == 'p'
48225ec6aefSMasatake YAMATO 			|| c == 'i')
48325ec6aefSMasatake YAMATO 			tokenPutc (token, c);
48425ec6aefSMasatake YAMATO 		else
48525ec6aefSMasatake YAMATO 		{
48625ec6aefSMasatake YAMATO 			ungetcToInputFile (c);
48725ec6aefSMasatake YAMATO 			break;
48825ec6aefSMasatake YAMATO 		}
48925ec6aefSMasatake YAMATO 	}
49025ec6aefSMasatake YAMATO }
49125ec6aefSMasatake YAMATO 
readSymbol(tokenInfo * const token,void * data)49225ec6aefSMasatake YAMATO static void readSymbol (tokenInfo *const token, void *data)
49325ec6aefSMasatake YAMATO {
49425ec6aefSMasatake YAMATO 	int c;
49525ec6aefSMasatake YAMATO 	while ((c = getcFromInputFile ()))
49625ec6aefSMasatake YAMATO 	{
49725ec6aefSMasatake YAMATO 		if (isalnum (c) || c == '.' || c == '_')
49825ec6aefSMasatake YAMATO 			tokenPutc (token, c);
49925ec6aefSMasatake YAMATO 		else
50025ec6aefSMasatake YAMATO 		{
50125ec6aefSMasatake YAMATO 			ungetcToInputFile (c);
50225ec6aefSMasatake YAMATO 			break;
50325ec6aefSMasatake YAMATO 		}
50425ec6aefSMasatake YAMATO 	}
50525ec6aefSMasatake YAMATO }
50625ec6aefSMasatake YAMATO 
resolveKeyword(vString * string)50725ec6aefSMasatake YAMATO static keywordId resolveKeyword (vString *string)
50825ec6aefSMasatake YAMATO {
50925ec6aefSMasatake YAMATO 	char *s = vStringValue (string);
51025ec6aefSMasatake YAMATO 	static langType lang = LANG_AUTO;
51125ec6aefSMasatake YAMATO 
51225ec6aefSMasatake YAMATO 	if (lang == LANG_AUTO)
51325ec6aefSMasatake YAMATO 		lang = getInputLanguage ();
51425ec6aefSMasatake YAMATO 
51525ec6aefSMasatake YAMATO 	return lookupCaseKeyword (s, lang);
51625ec6aefSMasatake YAMATO }
51725ec6aefSMasatake YAMATO 
signatureExpectingParameter(vString * signature)51825ec6aefSMasatake YAMATO static bool signatureExpectingParameter (vString *signature)
51925ec6aefSMasatake YAMATO {
52025ec6aefSMasatake YAMATO 	if (vStringLast (signature) == '(')
52125ec6aefSMasatake YAMATO 		return true;
52225ec6aefSMasatake YAMATO 
52325ec6aefSMasatake YAMATO 	for (size_t i = vStringLength (signature); i > 0; i--)
52425ec6aefSMasatake YAMATO 	{
5257171591bSMasatake YAMATO 		char c = vStringChar (signature, i - 1);
52625ec6aefSMasatake YAMATO 		if (c == ' ')
52725ec6aefSMasatake YAMATO 			continue;
52825ec6aefSMasatake YAMATO 		else if (c == ',')
52925ec6aefSMasatake YAMATO 			return true;
53025ec6aefSMasatake YAMATO 		break;
53125ec6aefSMasatake YAMATO 	}
53225ec6aefSMasatake YAMATO 	return false;
53325ec6aefSMasatake YAMATO }
53425ec6aefSMasatake YAMATO 
readToken(tokenInfo * const token,void * data)53525ec6aefSMasatake YAMATO static void readToken (tokenInfo *const token, void *data)
53625ec6aefSMasatake YAMATO {
53725ec6aefSMasatake YAMATO 	int c, c0;
53825ec6aefSMasatake YAMATO 
53930fa30b1SMasatake YAMATO 	token->type = TOKEN_R_UNDEFINED;
54025ec6aefSMasatake YAMATO 	token->keyword = KEYWORD_NONE;
54125ec6aefSMasatake YAMATO 	vStringClear (token->string);
54225ec6aefSMasatake YAMATO 
54325ec6aefSMasatake YAMATO 	do
54425ec6aefSMasatake YAMATO 		c = getcFromInputFile ();
54525ec6aefSMasatake YAMATO 	while (c == ' ' || c== '\t' || c == '\f');
54625ec6aefSMasatake YAMATO 
54725ec6aefSMasatake YAMATO 	token->lineNumber   = getInputLineNumber ();
54825ec6aefSMasatake YAMATO 	token->filePosition = getInputFilePosition ();
54925ec6aefSMasatake YAMATO 
55025ec6aefSMasatake YAMATO 	switch (c)
55125ec6aefSMasatake YAMATO 	{
55225ec6aefSMasatake YAMATO 	case EOF:
55330fa30b1SMasatake YAMATO 		token->type = TOKEN_R_EOF;
55425ec6aefSMasatake YAMATO 		break;
55525ec6aefSMasatake YAMATO 	case '#':
55625ec6aefSMasatake YAMATO 		while (1)
55725ec6aefSMasatake YAMATO 		{
55825ec6aefSMasatake YAMATO 			c = getcFromInputFile ();
55925ec6aefSMasatake YAMATO 			if (c == EOF)
56025ec6aefSMasatake YAMATO 			{
56130fa30b1SMasatake YAMATO 				token->type = TOKEN_R_EOF;
56225ec6aefSMasatake YAMATO 				break;
56325ec6aefSMasatake YAMATO 			}
56425ec6aefSMasatake YAMATO 			else if (c == '\n')
56525ec6aefSMasatake YAMATO 			{
56625ec6aefSMasatake YAMATO 				token->type = c;
56725ec6aefSMasatake YAMATO 				tokenPutc (token, c);
56825ec6aefSMasatake YAMATO 				break;
56925ec6aefSMasatake YAMATO 			}
57025ec6aefSMasatake YAMATO 		}
57125ec6aefSMasatake YAMATO 		break;
57225ec6aefSMasatake YAMATO 	case '\n':
57325ec6aefSMasatake YAMATO 	case ';':
57425ec6aefSMasatake YAMATO 		token->type = c;
57525ec6aefSMasatake YAMATO 		tokenPutc (token, c);
57625ec6aefSMasatake YAMATO 		break;
57725ec6aefSMasatake YAMATO 	case '\'':
57825ec6aefSMasatake YAMATO 	case '"':
57925ec6aefSMasatake YAMATO 	case '`':
58030fa30b1SMasatake YAMATO 		token->type = TOKEN_R_STRING;
58125ec6aefSMasatake YAMATO 		tokenPutc (token, c);
58225ec6aefSMasatake YAMATO 		readString (token, data);
58325ec6aefSMasatake YAMATO 		break;
58425ec6aefSMasatake YAMATO 	case '+':
58525ec6aefSMasatake YAMATO 	case '/':
58625ec6aefSMasatake YAMATO 	case '^':
58725ec6aefSMasatake YAMATO 	case '~':
58830fa30b1SMasatake YAMATO 		token->type = TOKEN_R_OPERATOR;
58925ec6aefSMasatake YAMATO 		tokenPutc (token, c);
59025ec6aefSMasatake YAMATO 		break;
59125ec6aefSMasatake YAMATO 	case ':':
59230fa30b1SMasatake YAMATO 		token->type = TOKEN_R_OPERATOR;
59325ec6aefSMasatake YAMATO 		tokenPutc (token, c);
59425ec6aefSMasatake YAMATO 		c = getcFromInputFile ();
59525ec6aefSMasatake YAMATO 		if (c == ':')
59625ec6aefSMasatake YAMATO 		{
59725ec6aefSMasatake YAMATO 			tokenPutc (token, c);
59830fa30b1SMasatake YAMATO 			token->type = TOKEN_R_SCOPE;
59925ec6aefSMasatake YAMATO 			c = getcFromInputFile ();
60025ec6aefSMasatake YAMATO 			if (c == ':')
60125ec6aefSMasatake YAMATO 				tokenPutc (token, c);
60225ec6aefSMasatake YAMATO 			else
60325ec6aefSMasatake YAMATO 				ungetcToInputFile (c);
60425ec6aefSMasatake YAMATO 		}
60525ec6aefSMasatake YAMATO 		else
60625ec6aefSMasatake YAMATO 			ungetcToInputFile (c);
60725ec6aefSMasatake YAMATO 		break;
60825ec6aefSMasatake YAMATO 	case '&':
60925ec6aefSMasatake YAMATO 	case '|':
61025ec6aefSMasatake YAMATO 	case '*':
61130fa30b1SMasatake YAMATO 		token->type = TOKEN_R_OPERATOR;
61225ec6aefSMasatake YAMATO 		tokenPutc (token, c);
61325ec6aefSMasatake YAMATO 		c0 = getcFromInputFile ();
61425ec6aefSMasatake YAMATO 		if (c == c0)
61525ec6aefSMasatake YAMATO 			tokenPutc (token, c0);
61625ec6aefSMasatake YAMATO 		else
61725ec6aefSMasatake YAMATO 			ungetcToInputFile (c0);
61825ec6aefSMasatake YAMATO 		break;
61925ec6aefSMasatake YAMATO 	case '=':
62030fa30b1SMasatake YAMATO 		token->type = TOKEN_R_OPERATOR;
62125ec6aefSMasatake YAMATO 		tokenPutc (token, c);
62225ec6aefSMasatake YAMATO 		c = getcFromInputFile ();
62325ec6aefSMasatake YAMATO 		if (c == '=')
62425ec6aefSMasatake YAMATO 			tokenPutc (token, c);
62525ec6aefSMasatake YAMATO 		else
62625ec6aefSMasatake YAMATO 		{
62725ec6aefSMasatake YAMATO 			token->type = '=';
62825ec6aefSMasatake YAMATO 			ungetcToInputFile (c);
62925ec6aefSMasatake YAMATO 		}
63025ec6aefSMasatake YAMATO 		break;
63125ec6aefSMasatake YAMATO 	case '-':
63230fa30b1SMasatake YAMATO 		token->type = TOKEN_R_OPERATOR;
63325ec6aefSMasatake YAMATO 		tokenPutc (token, c);
63425ec6aefSMasatake YAMATO 		c = getcFromInputFile ();
63525ec6aefSMasatake YAMATO 		if (c == '>')
63625ec6aefSMasatake YAMATO 		{
63730fa30b1SMasatake YAMATO 			token->type = TOKEN_R_RASSIGN;
63825ec6aefSMasatake YAMATO 			tokenPutc (token, c);
63925ec6aefSMasatake YAMATO 			c = getcFromInputFile ();
64025ec6aefSMasatake YAMATO 			if (c == '>')
64125ec6aefSMasatake YAMATO 				tokenPutc (token, c);
64225ec6aefSMasatake YAMATO 			else
64325ec6aefSMasatake YAMATO 				ungetcToInputFile (c);
64425ec6aefSMasatake YAMATO 		}
64525ec6aefSMasatake YAMATO 		else
64625ec6aefSMasatake YAMATO 			ungetcToInputFile (c);
64725ec6aefSMasatake YAMATO 		break;
64825ec6aefSMasatake YAMATO 	case '>':
64930fa30b1SMasatake YAMATO 		token->type = TOKEN_R_OPERATOR;
65025ec6aefSMasatake YAMATO 		tokenPutc (token, c);
65125ec6aefSMasatake YAMATO 		c = getcFromInputFile ();
65225ec6aefSMasatake YAMATO 		if (c == '=')
65325ec6aefSMasatake YAMATO 			tokenPutc (token, c);
65425ec6aefSMasatake YAMATO 		else
65525ec6aefSMasatake YAMATO 			ungetcToInputFile (c);
65625ec6aefSMasatake YAMATO 		break;
65725ec6aefSMasatake YAMATO 	case '<':
65830fa30b1SMasatake YAMATO 		token->type = TOKEN_R_OPERATOR;
65925ec6aefSMasatake YAMATO 		tokenPutc (token, c);
66025ec6aefSMasatake YAMATO 		c = getcFromInputFile ();
66125ec6aefSMasatake YAMATO 
66225ec6aefSMasatake YAMATO 		/* <<- */
66325ec6aefSMasatake YAMATO 		if (c == '<')
66425ec6aefSMasatake YAMATO 		{
66525ec6aefSMasatake YAMATO 			tokenPutc (token, c);
66625ec6aefSMasatake YAMATO 			c = getcFromInputFile ();
66725ec6aefSMasatake YAMATO 		}
66825ec6aefSMasatake YAMATO 
66925ec6aefSMasatake YAMATO 		if (c == '-')
67025ec6aefSMasatake YAMATO 		{
67130fa30b1SMasatake YAMATO 			token->type = TOKEN_R_LASSIGN;
67225ec6aefSMasatake YAMATO 			tokenPutc (token, c);
67325ec6aefSMasatake YAMATO 		}
67425ec6aefSMasatake YAMATO 		else if (c == '=')
67525ec6aefSMasatake YAMATO 			tokenPutc (token, c);
67625ec6aefSMasatake YAMATO 		else
67725ec6aefSMasatake YAMATO 			ungetcToInputFile (c);
67825ec6aefSMasatake YAMATO 		break;
67925ec6aefSMasatake YAMATO 	case '%':
68030fa30b1SMasatake YAMATO 		token->type = TOKEN_R_OPERATOR;
68125ec6aefSMasatake YAMATO 		tokenPutc (token, c);
68225ec6aefSMasatake YAMATO 		do
68325ec6aefSMasatake YAMATO 		{
68425ec6aefSMasatake YAMATO 			c = getcFromInputFile ();
68525ec6aefSMasatake YAMATO 			if (c == EOF)
68625ec6aefSMasatake YAMATO 				break;
68725ec6aefSMasatake YAMATO 
68825ec6aefSMasatake YAMATO 			tokenPutc (token, c);
68925ec6aefSMasatake YAMATO 			if (c == '%')
69025ec6aefSMasatake YAMATO 				break;
69125ec6aefSMasatake YAMATO 		}
69225ec6aefSMasatake YAMATO 		while (1);
69325ec6aefSMasatake YAMATO 		break;
69425ec6aefSMasatake YAMATO 	case '!':
69530fa30b1SMasatake YAMATO 		token->type = TOKEN_R_OPERATOR;
69625ec6aefSMasatake YAMATO 		tokenPutc (token, c);
69725ec6aefSMasatake YAMATO 		c = getcFromInputFile ();
69825ec6aefSMasatake YAMATO 		if (c == '=')
69925ec6aefSMasatake YAMATO 			tokenPutc (token, c);
70025ec6aefSMasatake YAMATO 		else
70125ec6aefSMasatake YAMATO 			ungetcToInputFile (c);
70225ec6aefSMasatake YAMATO 		break;
70325ec6aefSMasatake YAMATO 	case '{':
70425ec6aefSMasatake YAMATO 	case '}':
70525ec6aefSMasatake YAMATO 	case '(':
70625ec6aefSMasatake YAMATO 	case ')':
707e5be4d27SMasatake YAMATO 	case '[':
708e5be4d27SMasatake YAMATO 	case ']':
70925ec6aefSMasatake YAMATO 	case ',':
71025ec6aefSMasatake YAMATO 	case '$':
71125ec6aefSMasatake YAMATO 	case '@':
71225ec6aefSMasatake YAMATO 		token->type = c;
71325ec6aefSMasatake YAMATO 		tokenPutc (token, c);
71425ec6aefSMasatake YAMATO 		break;
71525ec6aefSMasatake YAMATO 	case '.':
71625ec6aefSMasatake YAMATO 		tokenPutc (token, c);
71725ec6aefSMasatake YAMATO 		c = getcFromInputFile ();
71825ec6aefSMasatake YAMATO 		if (isdigit(c))
71925ec6aefSMasatake YAMATO 		{
72030fa30b1SMasatake YAMATO 			token->type = TOKEN_R_NUMBER;
72125ec6aefSMasatake YAMATO 			tokenPutc (token, c);
72225ec6aefSMasatake YAMATO 			readNumber(token, data);
72325ec6aefSMasatake YAMATO 		}
72425ec6aefSMasatake YAMATO 		else if (isalpha (c) || c == '_')
72525ec6aefSMasatake YAMATO 		{
72630fa30b1SMasatake YAMATO 			token->type = TOKEN_R_SYMBOL;
72725ec6aefSMasatake YAMATO 			tokenPutc (token, c);
72825ec6aefSMasatake YAMATO 			readSymbol (token, data);
72925ec6aefSMasatake YAMATO 
73025ec6aefSMasatake YAMATO 			token->keyword = resolveKeyword (token->string);
73125ec6aefSMasatake YAMATO 			if (token->keyword != KEYWORD_NONE)
73230fa30b1SMasatake YAMATO 				token->type = TOKEN_R_KEYWORD;
73325ec6aefSMasatake YAMATO 		}
73425ec6aefSMasatake YAMATO 		else if (c == '.')
73525ec6aefSMasatake YAMATO 		{
73630fa30b1SMasatake YAMATO 			token->type = TOKEN_R_DOTS;
73725ec6aefSMasatake YAMATO 			tokenPutc (token, c);
73825ec6aefSMasatake YAMATO 
73925ec6aefSMasatake YAMATO 			c = getcFromInputFile ();
74025ec6aefSMasatake YAMATO 			if (c == '.')
74125ec6aefSMasatake YAMATO 				tokenPutc (token, c);
74225ec6aefSMasatake YAMATO 			else if (isdigit(c))
74325ec6aefSMasatake YAMATO 			{
74430fa30b1SMasatake YAMATO 				token->type = TOKEN_R_DOTS_N;
74525ec6aefSMasatake YAMATO 				do
74625ec6aefSMasatake YAMATO 				{
74725ec6aefSMasatake YAMATO 					tokenPutc (token, c);
74825ec6aefSMasatake YAMATO 					c = getcFromInputFile ();
74925ec6aefSMasatake YAMATO 				}
75025ec6aefSMasatake YAMATO 				while (isdigit(c));
75125ec6aefSMasatake YAMATO 				ungetcToInputFile (c);
75225ec6aefSMasatake YAMATO 			}
75325ec6aefSMasatake YAMATO 			else if (isalpha (c) || c == '_')
75425ec6aefSMasatake YAMATO 			{
75530fa30b1SMasatake YAMATO 				token->type = TOKEN_R_SYMBOL;
75625ec6aefSMasatake YAMATO 				tokenPutc (token, c);
75725ec6aefSMasatake YAMATO 				readSymbol (token, data);
75825ec6aefSMasatake YAMATO 
75925ec6aefSMasatake YAMATO 				token->keyword = resolveKeyword (token->string);
76025ec6aefSMasatake YAMATO 				if (token->keyword != KEYWORD_NONE)
76130fa30b1SMasatake YAMATO 					token->type = TOKEN_R_KEYWORD;
76225ec6aefSMasatake YAMATO 			}
76325ec6aefSMasatake YAMATO 			else
76425ec6aefSMasatake YAMATO 			{
76530fa30b1SMasatake YAMATO 				token->type = TOKEN_R_UNDEFINED;
76625ec6aefSMasatake YAMATO 				ungetcToInputFile (c);
76725ec6aefSMasatake YAMATO 			}
76825ec6aefSMasatake YAMATO 		}
76925ec6aefSMasatake YAMATO 		break;
77025ec6aefSMasatake YAMATO 	default:
77125ec6aefSMasatake YAMATO 		tokenPutc (token, c);
77225ec6aefSMasatake YAMATO 		if (isdigit (c))
77325ec6aefSMasatake YAMATO 		{
77430fa30b1SMasatake YAMATO 			token->type = TOKEN_R_NUMBER;
77525ec6aefSMasatake YAMATO 			readNumber(token, data);
77625ec6aefSMasatake YAMATO 		}
77725ec6aefSMasatake YAMATO 		else if (isalpha (c))
77825ec6aefSMasatake YAMATO 		{
77930fa30b1SMasatake YAMATO 			token->type = TOKEN_R_SYMBOL;
78025ec6aefSMasatake YAMATO 			readSymbol (token, data);
78125ec6aefSMasatake YAMATO 
78225ec6aefSMasatake YAMATO 			token->keyword = resolveKeyword (token->string);
78325ec6aefSMasatake YAMATO 			if (token->keyword != KEYWORD_NONE)
78430fa30b1SMasatake YAMATO 				token->type = TOKEN_R_KEYWORD;
78525ec6aefSMasatake YAMATO 		}
78625ec6aefSMasatake YAMATO 		else
78730fa30b1SMasatake YAMATO 			token->type = TOKEN_R_UNDEFINED;
78825ec6aefSMasatake YAMATO 		break;
78925ec6aefSMasatake YAMATO 	}
79025ec6aefSMasatake YAMATO 
79125ec6aefSMasatake YAMATO 	/* Handle parameters in a signature */
79230fa30b1SMasatake YAMATO 	if (R(token)->signature && !tokenIsType(token, R_EOF) && !tokenIsTypeVal(token, '\n'))
79325ec6aefSMasatake YAMATO 	{
79425ec6aefSMasatake YAMATO 		vString *signature = R (token)->signature;
79525ec6aefSMasatake YAMATO 
79625ec6aefSMasatake YAMATO 		if (tokenIsTypeVal (token, '('))
79725ec6aefSMasatake YAMATO 			R (token)->parenDepth++;
79825ec6aefSMasatake YAMATO 		else if (tokenIsTypeVal (token, ')'))
79925ec6aefSMasatake YAMATO 			R (token)->parenDepth--;
80025ec6aefSMasatake YAMATO 
801c1117bc9SMasatake YAMATO 		if (R (token)->kindIndexForParams != KIND_GHOST_INDEX
802c1117bc9SMasatake YAMATO 			&& R (token)->parenDepth == 1 && tokenIsType (token, R_SYMBOL)
80325ec6aefSMasatake YAMATO 			&& signatureExpectingParameter (signature))
804c1117bc9SMasatake YAMATO 			makeSimpleRTag (token, R (token)->scopeIndex, false,
805c1117bc9SMasatake YAMATO 							R (token)->kindIndexForParams, NULL);
80625ec6aefSMasatake YAMATO 
80725ec6aefSMasatake YAMATO 		if (vStringLast (signature) != '(' &&
80825ec6aefSMasatake YAMATO 			!tokenIsTypeVal (token, ',') &&
80925ec6aefSMasatake YAMATO 			!tokenIsTypeVal (token, ')'))
81025ec6aefSMasatake YAMATO 			vStringPut (signature, ' ');
81125ec6aefSMasatake YAMATO 		vStringCat (signature, token->string);
81225ec6aefSMasatake YAMATO 	}
81325ec6aefSMasatake YAMATO }
81425ec6aefSMasatake YAMATO 
8158fa3486cSMasatake YAMATO #define newRToken rNewToken
rNewToken(void)8168fa3486cSMasatake YAMATO extern tokenInfo *rNewToken (void)
81725ec6aefSMasatake YAMATO {
81825ec6aefSMasatake YAMATO 	return newToken (&rTokenInfoClass);
81925ec6aefSMasatake YAMATO }
82025ec6aefSMasatake YAMATO 
82130fa30b1SMasatake YAMATO #define tokenReadNoNewline rTokenReadNoNewline
rTokenReadNoNewline(tokenInfo * const token)82230fa30b1SMasatake YAMATO extern void rTokenReadNoNewline (tokenInfo *const token)
82325ec6aefSMasatake YAMATO {
82425ec6aefSMasatake YAMATO 	while (1)
82525ec6aefSMasatake YAMATO 	{
82625ec6aefSMasatake YAMATO 		tokenRead(token);
82725ec6aefSMasatake YAMATO 		if (!tokenIsTypeVal (token, '\n'))
82825ec6aefSMasatake YAMATO 			break;
82925ec6aefSMasatake YAMATO 	}
83025ec6aefSMasatake YAMATO }
83125ec6aefSMasatake YAMATO 
setupCollectingSignature(tokenInfo * const token,vString * signature,int kindIndexForParams,int corkIndex)832c1117bc9SMasatake YAMATO static void setupCollectingSignature (tokenInfo *const token,
833c1117bc9SMasatake YAMATO 									  vString   *signature,
834c1117bc9SMasatake YAMATO 									  int kindIndexForParams,
835c1117bc9SMasatake YAMATO 									  int corkIndex)
836c1117bc9SMasatake YAMATO {
837c1117bc9SMasatake YAMATO 	R (token)->signature = signature;
838c1117bc9SMasatake YAMATO 	R (token)->kindIndexForParams = kindIndexForParams;
839c1117bc9SMasatake YAMATO 	R (token)->scopeIndex = corkIndex;
840c1117bc9SMasatake YAMATO 	R (token)->parenDepth = 1;
841c1117bc9SMasatake YAMATO }
842c1117bc9SMasatake YAMATO 
rSetupCollectingSignature(tokenInfo * const token,vString * signature)843c1117bc9SMasatake YAMATO extern void rSetupCollectingSignature (tokenInfo *const token,
844c1117bc9SMasatake YAMATO 									   vString   *signature)
845c1117bc9SMasatake YAMATO {
846c1117bc9SMasatake YAMATO 	setupCollectingSignature (token, signature,
847c1117bc9SMasatake YAMATO 							  KIND_GHOST_INDEX, CORK_NIL);
848c1117bc9SMasatake YAMATO }
849c1117bc9SMasatake YAMATO 
teardownCollectingSignature(tokenInfo * const token)850c1117bc9SMasatake YAMATO static void teardownCollectingSignature (tokenInfo *const token)
851c1117bc9SMasatake YAMATO {
852c1117bc9SMasatake YAMATO 	R (token)->parenDepth = 0;
853c1117bc9SMasatake YAMATO 	R (token)->scopeIndex = CORK_NIL;
854c1117bc9SMasatake YAMATO 	R (token)->kindIndexForParams = KIND_GHOST_INDEX;
855c1117bc9SMasatake YAMATO 	R (token)->signature = NULL;
856c1117bc9SMasatake YAMATO }
857c1117bc9SMasatake YAMATO 
rTeardownCollectingSignature(tokenInfo * const token)858c1117bc9SMasatake YAMATO extern void rTeardownCollectingSignature (tokenInfo *const token)
859c1117bc9SMasatake YAMATO {
860c1117bc9SMasatake YAMATO 	teardownCollectingSignature (token);
861c1117bc9SMasatake YAMATO }
862c1117bc9SMasatake YAMATO 
getKindForToken(tokenInfo * const token)8633d0afc4dSMasatake YAMATO static int getKindForToken (tokenInfo *const token)
8643d0afc4dSMasatake YAMATO {
8653d0afc4dSMasatake YAMATO 	if (tokenIsKeyword (token, R_FUNCTION))
8663d0afc4dSMasatake YAMATO 		return K_FUNCTION;
8673d0afc4dSMasatake YAMATO 	else if (tokenIsKeyword (token, R_C))
8683d0afc4dSMasatake YAMATO 		return K_VECTOR;
8692b000035SMasatake YAMATO 	else if (tokenIsKeyword (token, R_LIST))
8702b000035SMasatake YAMATO 		return K_LIST;
87109bc94cdSMasatake YAMATO 	else if (tokenIsKeyword (token, R_DATAFRAME))
87209bc94cdSMasatake YAMATO 		return K_DATAFRAME;
8733d0afc4dSMasatake YAMATO 	return K_GLOBALVAR;
8743d0afc4dSMasatake YAMATO }
8753d0afc4dSMasatake YAMATO 
findNonPlaceholder(int corkIndex,tagEntryInfo * entry,void * data)876cd905678SMasatake YAMATO static bool findNonPlaceholder (int corkIndex, tagEntryInfo *entry, void *data)
877cd905678SMasatake YAMATO {
878cd905678SMasatake YAMATO 	bool *any_non_placehoders = data;
879cd905678SMasatake YAMATO 	if (!entry->placeholder)
880cd905678SMasatake YAMATO 	{
881cd905678SMasatake YAMATO 		*any_non_placehoders = true;
882cd905678SMasatake YAMATO 		return false;
883cd905678SMasatake YAMATO 	}
884cd905678SMasatake YAMATO 	return true;
885cd905678SMasatake YAMATO }
886cd905678SMasatake YAMATO 
parseRightSide(tokenInfo * const token,tokenInfo * const symbol,int parent)88725ec6aefSMasatake YAMATO static void parseRightSide (tokenInfo *const token, tokenInfo *const symbol, int parent)
88825ec6aefSMasatake YAMATO {
88925ec6aefSMasatake YAMATO 	R_TRACE_ENTER();
89025ec6aefSMasatake YAMATO 
89125ec6aefSMasatake YAMATO 	char *const assignment_operator = eStrdup (tokenString (token));
89225ec6aefSMasatake YAMATO 	vString *signature = NULL;
89325ec6aefSMasatake YAMATO 
89425ec6aefSMasatake YAMATO 	tokenReadNoNewline (token);
89525ec6aefSMasatake YAMATO 
8963d0afc4dSMasatake YAMATO 	int kind = getKindForToken (token);
8977ee2f972SMasatake YAMATO 
898228b74c1SMasatake YAMATO 	/* Call sub parsers */
8993d0afc4dSMasatake YAMATO 	int corkIndex = notifyReadRightSideSymbol (symbol,
900228b74c1SMasatake YAMATO 											   assignment_operator,
901228b74c1SMasatake YAMATO 											   parent,
902228b74c1SMasatake YAMATO 											   token);
903228b74c1SMasatake YAMATO 	if (corkIndex == CORK_NIL)
904228b74c1SMasatake YAMATO 	{
905228b74c1SMasatake YAMATO 		/* No subparser handle the symbol */
9062fc210b6SMasatake YAMATO 		corkIndex = makeSimpleRTag (symbol, parent, kind == K_FUNCTION,
907228b74c1SMasatake YAMATO 									kind,
908228b74c1SMasatake YAMATO 									assignment_operator);
909228b74c1SMasatake YAMATO 	}
910228b74c1SMasatake YAMATO 
9112fc210b6SMasatake YAMATO 	if (kind == K_FUNCTION)
91225ec6aefSMasatake YAMATO 	{
913228b74c1SMasatake YAMATO 		/* parse signature */
91425ec6aefSMasatake YAMATO 		tokenReadNoNewline (token);
91525ec6aefSMasatake YAMATO 		if (tokenIsTypeVal (token, '('))
91625ec6aefSMasatake YAMATO 		{
917ed1b6f16SMasatake YAMATO 			if (corkIndex == CORK_NIL)
918ed1b6f16SMasatake YAMATO 				tokenSkipOverPair (token);
919ed1b6f16SMasatake YAMATO 			else
920ed1b6f16SMasatake YAMATO 			{
92125ec6aefSMasatake YAMATO 				signature = vStringNewInit("(");
922c1117bc9SMasatake YAMATO 				setupCollectingSignature (token, signature, K_PARAM, corkIndex);
92325ec6aefSMasatake YAMATO 				tokenSkipOverPair (token);
924c1117bc9SMasatake YAMATO 				teardownCollectingSignature (token);
925ed1b6f16SMasatake YAMATO 			}
92625ec6aefSMasatake YAMATO 			tokenReadNoNewline (token);
92725ec6aefSMasatake YAMATO 		}
92867cba2b6SMasatake YAMATO 		parent = (corkIndex == CORK_NIL
92967cba2b6SMasatake YAMATO 				  ? blackHoleIndex
93067cba2b6SMasatake YAMATO 				  : corkIndex);
93125ec6aefSMasatake YAMATO 	}
93209bc94cdSMasatake YAMATO 	else if (kind == K_VECTOR || kind == K_LIST || kind == K_DATAFRAME)
933cd905678SMasatake YAMATO 	{
934cd905678SMasatake YAMATO 		tokenRead (token);
935cd905678SMasatake YAMATO 		parsePair (token, corkIndex, NULL);
936cd905678SMasatake YAMATO 		tokenRead (token);
937cd905678SMasatake YAMATO 		parent = corkIndex;
938cd905678SMasatake YAMATO 	}
93925ec6aefSMasatake YAMATO 
94067cba2b6SMasatake YAMATO 	R_TRACE_TOKEN_TEXT("body", token, parent);
94125ec6aefSMasatake YAMATO 
94267cba2b6SMasatake YAMATO 	parseStatement (token, parent, false, false);
94325ec6aefSMasatake YAMATO 
94425ec6aefSMasatake YAMATO 	tagEntryInfo *tag = getEntryInCorkQueue (corkIndex);
94525ec6aefSMasatake YAMATO 	if (tag)
94625ec6aefSMasatake YAMATO 	{
94725ec6aefSMasatake YAMATO 		tag->extensionFields.endLine = token->lineNumber;
94825ec6aefSMasatake YAMATO 		if (signature)
94925ec6aefSMasatake YAMATO 		{
95025ec6aefSMasatake YAMATO 			tag->extensionFields.signature = vStringDeleteUnwrap(signature);
95125ec6aefSMasatake YAMATO 			signature = NULL;
95225ec6aefSMasatake YAMATO 		}
953cd905678SMasatake YAMATO 		/* If a vector has no named attribte and it has no lval,
954cd905678SMasatake YAMATO 		 * we don't make a tag for the vector. */
95509bc94cdSMasatake YAMATO 		if ((kind == K_VECTOR || kind == K_LIST || kind == K_DATAFRAME)
9562b000035SMasatake YAMATO 			&& *assignment_operator == '\0')
957cd905678SMasatake YAMATO 		{
958cd905678SMasatake YAMATO 			bool any_non_placehoders = false;
959cd905678SMasatake YAMATO 			foreachEntriesInScope (corkIndex, NULL,
960cd905678SMasatake YAMATO 								   findNonPlaceholder, &any_non_placehoders);
961cd905678SMasatake YAMATO 			if (!any_non_placehoders)
962cd905678SMasatake YAMATO 				tag->placeholder = 1;
963cd905678SMasatake YAMATO 		}
96425ec6aefSMasatake YAMATO 	}
96525ec6aefSMasatake YAMATO 
96625ec6aefSMasatake YAMATO 	vStringDelete (signature);	/* NULL is acceptable. */
96725ec6aefSMasatake YAMATO 	eFree (assignment_operator);
96825ec6aefSMasatake YAMATO 	R_TRACE_LEAVE();
96925ec6aefSMasatake YAMATO }
97025ec6aefSMasatake YAMATO 
9710c4eabdcSMasatake YAMATO /* Parse arguments for library and source. */
preParseExternalEntitiy(tokenInfo * const token,tokenInfo * const funcall)9720c4eabdcSMasatake YAMATO static bool preParseExternalEntitiy (tokenInfo *const token, tokenInfo *const funcall)
9730c4eabdcSMasatake YAMATO {
9740c4eabdcSMasatake YAMATO 	TRACE_ENTER();
9750c4eabdcSMasatake YAMATO 
9760c4eabdcSMasatake YAMATO 	bool r = true;
9770c4eabdcSMasatake YAMATO 	tokenInfo *prefetch_token = newRToken ();
9780c4eabdcSMasatake YAMATO 
9790c4eabdcSMasatake YAMATO 	tokenReadNoNewline (prefetch_token);
98030fa30b1SMasatake YAMATO 	if (tokenIsType (prefetch_token, R_SYMBOL)
98130fa30b1SMasatake YAMATO 		|| tokenIsType (prefetch_token, R_STRING))
9820c4eabdcSMasatake YAMATO 	{
9830c4eabdcSMasatake YAMATO 		tokenInfo *const loaded_obj_token = newTokenByCopying (prefetch_token);
9840c4eabdcSMasatake YAMATO 		tokenReadNoNewline (prefetch_token);
9850c4eabdcSMasatake YAMATO 		if (tokenIsTypeVal (prefetch_token, ')')
9860c4eabdcSMasatake YAMATO 			|| tokenIsTypeVal (prefetch_token, ','))
9870c4eabdcSMasatake YAMATO 		{
9880c4eabdcSMasatake YAMATO 			if (tokenIsTypeVal (prefetch_token, ')'))
9890c4eabdcSMasatake YAMATO 				r = false;
9900c4eabdcSMasatake YAMATO 
9910c4eabdcSMasatake YAMATO 			makeSimpleRefTag (loaded_obj_token->string,
99230fa30b1SMasatake YAMATO 							  (tokenIsKeyword (funcall, R_LIBRARY)
9930c4eabdcSMasatake YAMATO 							   ? K_LIBRARY
9940c4eabdcSMasatake YAMATO 							   : K_SOURCE),
99530fa30b1SMasatake YAMATO 							  (tokenIsKeyword (funcall, R_LIBRARY)
9960c4eabdcSMasatake YAMATO 							   ? (strcmp (tokenString(funcall), "library") == 0
9970c4eabdcSMasatake YAMATO 								  ? R_LIBRARY_ATTACHED_BY_LIBRARY
9980c4eabdcSMasatake YAMATO 								  : R_LIBRARY_ATTACHED_BY_REQUIRE)
9990c4eabdcSMasatake YAMATO 							   : R_SOURCE_LOADED_BY_SOURCE));
10000c4eabdcSMasatake YAMATO 			tokenDelete (loaded_obj_token);
10010c4eabdcSMasatake YAMATO 		}
10020c4eabdcSMasatake YAMATO 		else if (tokenIsEOF (prefetch_token))
10030c4eabdcSMasatake YAMATO 		{
10040c4eabdcSMasatake YAMATO 			tokenCopy (token, prefetch_token);
10050c4eabdcSMasatake YAMATO 			tokenDelete (loaded_obj_token);
10060c4eabdcSMasatake YAMATO 			r = false;
10070c4eabdcSMasatake YAMATO 		}
10080c4eabdcSMasatake YAMATO 		else
10090c4eabdcSMasatake YAMATO 		{
10100c4eabdcSMasatake YAMATO 			tokenUnread (prefetch_token);
10110c4eabdcSMasatake YAMATO 			tokenUnread (loaded_obj_token);
10120c4eabdcSMasatake YAMATO 			tokenDelete (loaded_obj_token);
10130c4eabdcSMasatake YAMATO 		}
10140c4eabdcSMasatake YAMATO 	}
10150c4eabdcSMasatake YAMATO 	else if (tokenIsEOF (prefetch_token))
10160c4eabdcSMasatake YAMATO 	{
10170c4eabdcSMasatake YAMATO 		tokenCopy (token, prefetch_token);
10180c4eabdcSMasatake YAMATO 		r = false;
10190c4eabdcSMasatake YAMATO 	}
10200c4eabdcSMasatake YAMATO 	else
10210c4eabdcSMasatake YAMATO 		tokenUnread (prefetch_token);
10220c4eabdcSMasatake YAMATO 
10230c4eabdcSMasatake YAMATO 	tokenDelete (prefetch_token);
10240c4eabdcSMasatake YAMATO 
10250c4eabdcSMasatake YAMATO 	TRACE_LEAVE_TEXT(r
10260c4eabdcSMasatake YAMATO 					 ? "unread tokens and request parsing again to the upper context"
10270c4eabdcSMasatake YAMATO 					 : "parse all arguments");
10280c4eabdcSMasatake YAMATO 	return r;
10290c4eabdcSMasatake YAMATO }
10300c4eabdcSMasatake YAMATO 
preParseLoopCounter(tokenInfo * const token,int parent)103182036e8fSMasatake YAMATO static bool preParseLoopCounter(tokenInfo *const token, int parent)
103282036e8fSMasatake YAMATO {
103382036e8fSMasatake YAMATO 	bool r = true;
103482036e8fSMasatake YAMATO 	TRACE_ENTER();
103582036e8fSMasatake YAMATO 
103682036e8fSMasatake YAMATO 	tokenReadNoNewline (token);
103730fa30b1SMasatake YAMATO 	if (tokenIsType (token, R_SYMBOL))
1038bd0d90a5SMasatake YAMATO 		makeSimpleRTag (token, parent, false, K_GLOBALVAR, NULL);
103982036e8fSMasatake YAMATO 
104082036e8fSMasatake YAMATO 	if (tokenIsEOF (token)
104182036e8fSMasatake YAMATO 		|| tokenIsTypeVal (token, ')'))
104282036e8fSMasatake YAMATO 		r = false;
104382036e8fSMasatake YAMATO 
104482036e8fSMasatake YAMATO 	TRACE_LEAVE_TEXT(r
104582036e8fSMasatake YAMATO 					 ? "unread tokens and request parsing again to the upper context"
104682036e8fSMasatake YAMATO 					 : "parse all arguments");
104782036e8fSMasatake YAMATO 	return r;
104882036e8fSMasatake YAMATO }
104982036e8fSMasatake YAMATO 
10500c4eabdcSMasatake YAMATO 
10510c4eabdcSMasatake YAMATO /* If funcall is non-NULL, this pair represents the argument list for the function
10520c4eabdcSMasatake YAMATO  * call for FUNCALL. */
parsePair(tokenInfo * const token,int parent,tokenInfo * const funcall)10530c4eabdcSMasatake YAMATO static void parsePair (tokenInfo *const token, int parent, tokenInfo *const funcall)
105425ec6aefSMasatake YAMATO {
105525ec6aefSMasatake YAMATO 	R_TRACE_ENTER();
105625ec6aefSMasatake YAMATO 
105725ec6aefSMasatake YAMATO 	bool in_continuous_pair = tokenIsTypeVal (token, '(')
1058e5be4d27SMasatake YAMATO 		|| tokenIsTypeVal (token, '[');
10590c4eabdcSMasatake YAMATO 	bool is_funcall = funcall && tokenIsTypeVal (token, '(');
10600c4eabdcSMasatake YAMATO 	bool done = false;
10610c4eabdcSMasatake YAMATO 
10620c4eabdcSMasatake YAMATO 	if (is_funcall)
10630c4eabdcSMasatake YAMATO 	{
106430fa30b1SMasatake YAMATO 		if 	(tokenIsKeyword (funcall, R_LIBRARY) ||
106530fa30b1SMasatake YAMATO 			 tokenIsKeyword (funcall, R_SOURCE))
10660c4eabdcSMasatake YAMATO 			done = !preParseExternalEntitiy (token, funcall);
106730fa30b1SMasatake YAMATO 		else if (tokenIsKeyword (funcall, R_FOR))
106882036e8fSMasatake YAMATO 			done = !preParseLoopCounter (token, parent);
1069d1586adcSMasatake YAMATO 		else if (notifyReadFuncall (funcall, token, parent) != CORK_NIL)
1070d1586adcSMasatake YAMATO 			done = true;
10710c4eabdcSMasatake YAMATO 	}
10720c4eabdcSMasatake YAMATO 
10730c4eabdcSMasatake YAMATO 	if (done)
10740c4eabdcSMasatake YAMATO 	{
10750c4eabdcSMasatake YAMATO 		R_TRACE_LEAVE();
10760c4eabdcSMasatake YAMATO 		return;
10770c4eabdcSMasatake YAMATO 	}
107825ec6aefSMasatake YAMATO 
107925ec6aefSMasatake YAMATO 	do
108025ec6aefSMasatake YAMATO 	{
108125ec6aefSMasatake YAMATO 		tokenRead (token);
108225ec6aefSMasatake YAMATO 		R_TRACE_TOKEN_TEXT("inside pair", token, parent);
108305c79cb4SMasatake YAMATO 		parseStatement (token, parent, (funcall != NULL), in_continuous_pair);
108425ec6aefSMasatake YAMATO 	}
108525ec6aefSMasatake YAMATO 	while (! (tokenIsEOF (token)
108625ec6aefSMasatake YAMATO 			  || tokenIsTypeVal (token, ')')
108725ec6aefSMasatake YAMATO 			  || tokenIsTypeVal (token, '}')
1088e5be4d27SMasatake YAMATO 			  || tokenIsTypeVal (token, ']')));
108925ec6aefSMasatake YAMATO 	R_TRACE_LEAVE();
109025ec6aefSMasatake YAMATO }
109125ec6aefSMasatake YAMATO 
isAtConstructorInvocation(void)1092cd905678SMasatake YAMATO static bool isAtConstructorInvocation (void)
1093cd905678SMasatake YAMATO {
1094cd905678SMasatake YAMATO 	bool r = false;
1095cd905678SMasatake YAMATO 
1096cd905678SMasatake YAMATO 	tokenInfo *const token = newRToken ();
1097cd905678SMasatake YAMATO 	tokenRead (token);
1098cd905678SMasatake YAMATO 	if (tokenIsTypeVal (token, '('))
1099cd905678SMasatake YAMATO 		r = true;
1100cd905678SMasatake YAMATO 	tokenUnread (token);
1101cd905678SMasatake YAMATO 	tokenDelete (token);
1102cd905678SMasatake YAMATO 	return r;
1103cd905678SMasatake YAMATO }
1104cd905678SMasatake YAMATO 
parseStatement(tokenInfo * const token,int parent,bool in_arglist,bool in_continuous_pair)1105acc50dcaSMasatake YAMATO static bool parseStatement (tokenInfo *const token, int parent,
110605c79cb4SMasatake YAMATO 							bool in_arglist, bool in_continuous_pair)
110725ec6aefSMasatake YAMATO {
110825ec6aefSMasatake YAMATO 	R_TRACE_ENTER();
1109acc50dcaSMasatake YAMATO 	int last_count = rTokenInfoClass.read_counter;
111025ec6aefSMasatake YAMATO 
111125ec6aefSMasatake YAMATO 	do
111225ec6aefSMasatake YAMATO 	{
111325ec6aefSMasatake YAMATO 		if (tokenIsEOF (token))
111425ec6aefSMasatake YAMATO 			break;
111525ec6aefSMasatake YAMATO 		else if (tokenIsTypeVal (token, ';'))
111625ec6aefSMasatake YAMATO 		{
111725ec6aefSMasatake YAMATO 			R_TRACE_TOKEN_TEXT ("break with ;", token, parent);
111825ec6aefSMasatake YAMATO 			break;
111925ec6aefSMasatake YAMATO 		}
112025ec6aefSMasatake YAMATO 		else if (tokenIsTypeVal (token, '\n'))
112125ec6aefSMasatake YAMATO 		{
112225ec6aefSMasatake YAMATO 			R_TRACE_TOKEN_TEXT ("break with \\n", token, parent);
112325ec6aefSMasatake YAMATO 			break;
112425ec6aefSMasatake YAMATO 		}
11258db374deSMasatake YAMATO 		else if ((tokenIsKeyword (token, R_FUNCTION)
11262b000035SMasatake YAMATO 				  || ((tokenIsKeyword (token, R_C)
112709bc94cdSMasatake YAMATO 					   || tokenIsKeyword (token, R_LIST)
112809bc94cdSMasatake YAMATO 					   || tokenIsKeyword (token, R_DATAFRAME))
1129cd905678SMasatake YAMATO 					  && isAtConstructorInvocation ())))
1130ee670097SMasatake YAMATO 		{
1131ee670097SMasatake YAMATO 			/* This statement doesn't start with a symbol.
1132ee670097SMasatake YAMATO 			 * This function is not assigned to any symbol. */
1133ee670097SMasatake YAMATO 			tokenInfo *const anonfunc = newTokenByCopying (token);
11343d0afc4dSMasatake YAMATO 			int kind = getKindForToken (token);
1135cd905678SMasatake YAMATO 			anonGenerate (anonfunc->string,
1136cd905678SMasatake YAMATO 						  kindExtraInfo [kind].anon_prefix, kind);
1137ee670097SMasatake YAMATO 			tokenUnread (token);
1138ee670097SMasatake YAMATO 			vStringClear (token->string);
1139ee670097SMasatake YAMATO 			parseRightSide (token, anonfunc, parent);
1140ee670097SMasatake YAMATO 			tokenDelete (anonfunc);
1141ee670097SMasatake YAMATO 		}
114230fa30b1SMasatake YAMATO 		else if (tokenIsType (token, R_SYMBOL)
114330fa30b1SMasatake YAMATO 				 || tokenIsType (token, R_STRING)
114430fa30b1SMasatake YAMATO 				 || tokenIsType (token, R_KEYWORD))
114525ec6aefSMasatake YAMATO 		{
114625ec6aefSMasatake YAMATO 			tokenInfo *const symbol = newTokenByCopying (token);
114725ec6aefSMasatake YAMATO 
114825ec6aefSMasatake YAMATO 			if (in_continuous_pair)
114925ec6aefSMasatake YAMATO 				tokenReadNoNewline (token);
115025ec6aefSMasatake YAMATO 			else
115125ec6aefSMasatake YAMATO 				tokenRead (token);
115225ec6aefSMasatake YAMATO 
115330fa30b1SMasatake YAMATO 			if (tokenIsType (token, R_LASSIGN))
115425ec6aefSMasatake YAMATO 			{
115525ec6aefSMasatake YAMATO 				/* Assignment */
115625ec6aefSMasatake YAMATO 				parseRightSide (token, symbol, parent);
115725ec6aefSMasatake YAMATO 				R_TRACE_TOKEN_TEXT ("break with right side", token, parent);
115825ec6aefSMasatake YAMATO 				tokenDelete(symbol);
115925ec6aefSMasatake YAMATO 				break;
116025ec6aefSMasatake YAMATO 			}
116125ec6aefSMasatake YAMATO 			else if (tokenIsTypeVal (token, '='))
116225ec6aefSMasatake YAMATO 			{
116325ec6aefSMasatake YAMATO 				/* Assignment */
116405c79cb4SMasatake YAMATO 				if (in_arglist)
116525ec6aefSMasatake YAMATO 				{
116605c79cb4SMasatake YAMATO 					/* Ignore the left side symbol. */
116725ec6aefSMasatake YAMATO 					tokenRead (token);
116825ec6aefSMasatake YAMATO 					R_TRACE_TOKEN_TEXT("(in arg list) after = body", token, parent);
116925ec6aefSMasatake YAMATO 				}
117025ec6aefSMasatake YAMATO 				else
117125ec6aefSMasatake YAMATO 				{
117225ec6aefSMasatake YAMATO 					parseRightSide (token, symbol, parent);
117325ec6aefSMasatake YAMATO 					R_TRACE_TOKEN_TEXT ("break with right side", token, parent);
117425ec6aefSMasatake YAMATO 					tokenDelete(symbol);
117525ec6aefSMasatake YAMATO 					break;
117625ec6aefSMasatake YAMATO 				}
117725ec6aefSMasatake YAMATO 			}
117825ec6aefSMasatake YAMATO 			else if (tokenIsTypeVal (token, '('))
117925ec6aefSMasatake YAMATO 			{
118025ec6aefSMasatake YAMATO 				/* function call */
11810c4eabdcSMasatake YAMATO 				parsePair (token, parent, symbol);
118225ec6aefSMasatake YAMATO 				tokenRead (token);
118325ec6aefSMasatake YAMATO 				R_TRACE_TOKEN_TEXT("after arglist", token, parent);
118425ec6aefSMasatake YAMATO 			}
118525ec6aefSMasatake YAMATO 			else if (tokenIsTypeVal (token, '$')
118625ec6aefSMasatake YAMATO 					 || tokenIsTypeVal (token, '@')
118730fa30b1SMasatake YAMATO 					 || tokenIsType (token, R_SCOPE))
118825ec6aefSMasatake YAMATO 			{
118925ec6aefSMasatake YAMATO 				tokenReadNoNewline (token); /* Skip the next identifier */
119025ec6aefSMasatake YAMATO 				tokenRead (token);
119125ec6aefSMasatake YAMATO 				R_TRACE_TOKEN_TEXT("after $", token, parent);
119225ec6aefSMasatake YAMATO 			}
119325ec6aefSMasatake YAMATO 			else
119425ec6aefSMasatake YAMATO 				R_TRACE_TOKEN_TEXT("else after symbol", token, parent);
119525ec6aefSMasatake YAMATO 			tokenDelete(symbol);
119625ec6aefSMasatake YAMATO 		}
119730fa30b1SMasatake YAMATO 		else if (tokenIsType (token, R_RASSIGN))
119825ec6aefSMasatake YAMATO 		{
119925ec6aefSMasatake YAMATO 			char *const assignment_operator = eStrdup (tokenString (token));
120025ec6aefSMasatake YAMATO 			tokenReadNoNewline (token);
120130fa30b1SMasatake YAMATO 			if (tokenIsType (token, R_SYMBOL)
120230fa30b1SMasatake YAMATO 				|| tokenIsType (token, R_STRING))
120325ec6aefSMasatake YAMATO 			{
120430fa30b1SMasatake YAMATO 				makeSimpleRTag (token, parent, false,
1205bd0d90a5SMasatake YAMATO 								K_GLOBALVAR, assignment_operator);
120625ec6aefSMasatake YAMATO 				tokenRead (token);
120725ec6aefSMasatake YAMATO 			}
120825ec6aefSMasatake YAMATO 			eFree (assignment_operator);
120925ec6aefSMasatake YAMATO 			R_TRACE_TOKEN_TEXT("after ->", token, parent);
121025ec6aefSMasatake YAMATO 		}
121130fa30b1SMasatake YAMATO 		else if (tokenIsType (token, R_OPERATOR))
121225ec6aefSMasatake YAMATO 		{
121325ec6aefSMasatake YAMATO 			tokenReadNoNewline (token);
121425ec6aefSMasatake YAMATO 			R_TRACE_TOKEN_TEXT("after operator", token, parent);
121525ec6aefSMasatake YAMATO 		}
121625ec6aefSMasatake YAMATO 		else if (tokenIsTypeVal (token, '(')
121725ec6aefSMasatake YAMATO 				 || tokenIsTypeVal (token, '{')
1218e5be4d27SMasatake YAMATO 				 || tokenIsTypeVal (token, '['))
121925ec6aefSMasatake YAMATO 		{
12200c4eabdcSMasatake YAMATO 			parsePair (token, parent, NULL);
122125ec6aefSMasatake YAMATO 			tokenRead (token);
122225ec6aefSMasatake YAMATO 			R_TRACE_TOKEN_TEXT("after pair", token, parent);
122325ec6aefSMasatake YAMATO 		}
122425ec6aefSMasatake YAMATO 		else if (tokenIsTypeVal (token, ')')
122525ec6aefSMasatake YAMATO 				 || tokenIsTypeVal (token, '}')
1226e5be4d27SMasatake YAMATO 				 || tokenIsTypeVal (token, ']'))
122725ec6aefSMasatake YAMATO 		{
122825ec6aefSMasatake YAMATO 			R_TRACE_TOKEN_TEXT ("break with close", token, parent);
122925ec6aefSMasatake YAMATO 			break;
123025ec6aefSMasatake YAMATO 		}
123125ec6aefSMasatake YAMATO 		else if (tokenIsTypeVal (token, '$')
123225ec6aefSMasatake YAMATO 				 || tokenIsTypeVal (token, '@')
123330fa30b1SMasatake YAMATO 				 || tokenIsType (token, R_SCOPE))
123425ec6aefSMasatake YAMATO 		{
123525ec6aefSMasatake YAMATO 			tokenReadNoNewline (token); /* Skip the next identifier */
123625ec6aefSMasatake YAMATO 			tokenRead (token);
123725ec6aefSMasatake YAMATO 			R_TRACE_TOKEN_TEXT("after $", token, parent);
123825ec6aefSMasatake YAMATO 		}
123925ec6aefSMasatake YAMATO 		else
124025ec6aefSMasatake YAMATO 		{
124125ec6aefSMasatake YAMATO 			tokenRead (token);
124225ec6aefSMasatake YAMATO 			R_TRACE_TOKEN_TEXT("else", token, parent);
124325ec6aefSMasatake YAMATO 		}
124425ec6aefSMasatake YAMATO 	}
124525ec6aefSMasatake YAMATO 	while (!tokenIsEOF (token));
124625ec6aefSMasatake YAMATO 
124725ec6aefSMasatake YAMATO 	R_TRACE_LEAVE();
1248acc50dcaSMasatake YAMATO 
1249acc50dcaSMasatake YAMATO 	return (last_count != rTokenInfoClass.read_counter);
125025ec6aefSMasatake YAMATO }
125125ec6aefSMasatake YAMATO 
rParseStatement(tokenInfo * const token,int parentIndex,bool in_arglist)1252acc50dcaSMasatake YAMATO extern bool rParseStatement (tokenInfo *const token, int parentIndex, bool in_arglist)
125330fa30b1SMasatake YAMATO {
125430fa30b1SMasatake YAMATO 	pushLanguage (Lang_R);
1255acc50dcaSMasatake YAMATO 	bool r = parseStatement (token, parentIndex, in_arglist, true);
125630fa30b1SMasatake YAMATO 	popLanguage ();
1257acc50dcaSMasatake YAMATO 	return r;
125830fa30b1SMasatake YAMATO }
125930fa30b1SMasatake YAMATO 
notifyReadRightSideSymbol(tokenInfo * const symbol,const char * const assignmentOperator,int parent,tokenInfo * const token)126030fa30b1SMasatake YAMATO static  int notifyReadRightSideSymbol (tokenInfo *const symbol,
126130fa30b1SMasatake YAMATO 									   const char *const assignmentOperator,
126230fa30b1SMasatake YAMATO 									   int parent,
126330fa30b1SMasatake YAMATO 									   tokenInfo *const token)
126430fa30b1SMasatake YAMATO {
126530fa30b1SMasatake YAMATO 	subparser *sub;
126630fa30b1SMasatake YAMATO 	int q = CORK_NIL;
126730fa30b1SMasatake YAMATO 
126830fa30b1SMasatake YAMATO 	foreachSubparser (sub, false)
126930fa30b1SMasatake YAMATO 	{
127030fa30b1SMasatake YAMATO 		rSubparser *rsub = (rSubparser *)sub;
127130fa30b1SMasatake YAMATO 		if (rsub->readRightSideSymbol)
127230fa30b1SMasatake YAMATO 		{
127330fa30b1SMasatake YAMATO 			enterSubparser (sub);
127430fa30b1SMasatake YAMATO 			q = rsub->readRightSideSymbol (rsub, symbol, assignmentOperator, parent, token);
127530fa30b1SMasatake YAMATO 			leaveSubparser ();
127630fa30b1SMasatake YAMATO 			if (q != CORK_NIL)
127730fa30b1SMasatake YAMATO 				break;
127830fa30b1SMasatake YAMATO 		}
127930fa30b1SMasatake YAMATO 	}
128030fa30b1SMasatake YAMATO 
128130fa30b1SMasatake YAMATO 	return q;
128230fa30b1SMasatake YAMATO }
128330fa30b1SMasatake YAMATO 
makeSimpleSubparserTag(int langType,tokenInfo * const token,int parent,bool in_func,int kindInR,const char * assignmentOperator)128430fa30b1SMasatake YAMATO static  int makeSimpleSubparserTag (int langType,
128530fa30b1SMasatake YAMATO 									tokenInfo *const token, int parent,
128630fa30b1SMasatake YAMATO 									bool in_func, int kindInR,
128730fa30b1SMasatake YAMATO 									const char *assignmentOperator)
128830fa30b1SMasatake YAMATO {
128930fa30b1SMasatake YAMATO 	int q = CORK_NIL;
12904059520bSMasatake YAMATO 	subparser *sub = getLanguageSubparser (langType, false);
12914059520bSMasatake YAMATO 	if (sub)
129230fa30b1SMasatake YAMATO 	{
129330fa30b1SMasatake YAMATO 		rSubparser *rsub = (rSubparser *)sub;
129430fa30b1SMasatake YAMATO 		if (rsub->makeTagWithTranslation)
129530fa30b1SMasatake YAMATO 		{
129630fa30b1SMasatake YAMATO 			enterSubparser (sub);
129730fa30b1SMasatake YAMATO 			q = rsub->makeTagWithTranslation (rsub,
129830fa30b1SMasatake YAMATO 											  token, parent,
129930fa30b1SMasatake YAMATO 											  in_func, kindInR,
130030fa30b1SMasatake YAMATO 											  assignmentOperator);
130130fa30b1SMasatake YAMATO 			leaveSubparser ();
130230fa30b1SMasatake YAMATO 		}
130330fa30b1SMasatake YAMATO 	}
130430fa30b1SMasatake YAMATO 	return q;
130530fa30b1SMasatake YAMATO }
130630fa30b1SMasatake YAMATO 
askSubparserTagAcceptancy(tagEntryInfo * pe)130730fa30b1SMasatake YAMATO static  bool askSubparserTagAcceptancy (tagEntryInfo *pe)
130830fa30b1SMasatake YAMATO {
130930fa30b1SMasatake YAMATO 	bool q = false;
13104059520bSMasatake YAMATO 	subparser *sub = getLanguageSubparser (pe->langType, false);
131130fa30b1SMasatake YAMATO 	{
131230fa30b1SMasatake YAMATO 		rSubparser *rsub = (rSubparser *)sub;
131330fa30b1SMasatake YAMATO 		if (rsub->askTagAcceptancy)
131430fa30b1SMasatake YAMATO 		{
131530fa30b1SMasatake YAMATO 			enterSubparser (sub);
131630fa30b1SMasatake YAMATO 			q = rsub->askTagAcceptancy (rsub, pe);
131730fa30b1SMasatake YAMATO 			leaveSubparser ();
131830fa30b1SMasatake YAMATO 		}
131930fa30b1SMasatake YAMATO 	}
132030fa30b1SMasatake YAMATO 	return q;
132130fa30b1SMasatake YAMATO }
132230fa30b1SMasatake YAMATO 
askSubparserTagHasFunctionAlikeKind(tagEntryInfo * e)1323bd0d90a5SMasatake YAMATO static  bool askSubparserTagHasFunctionAlikeKind (tagEntryInfo *e)
1324bd0d90a5SMasatake YAMATO {
1325bd0d90a5SMasatake YAMATO 	bool q = false;
1326bd0d90a5SMasatake YAMATO 	pushLanguage (Lang_R);
1327bd0d90a5SMasatake YAMATO 	subparser *sub = getLanguageSubparser (e->langType, false);
1328bd0d90a5SMasatake YAMATO 	Assert (sub);
1329bd0d90a5SMasatake YAMATO 	popLanguage ();
1330bd0d90a5SMasatake YAMATO 	rSubparser *rsub = (rSubparser *)sub;
1331bd0d90a5SMasatake YAMATO 	if (rsub->hasFunctionAlikeKind)
1332bd0d90a5SMasatake YAMATO 	{
1333bd0d90a5SMasatake YAMATO 		enterSubparser (sub);
1334bd0d90a5SMasatake YAMATO 		q = rsub->hasFunctionAlikeKind (rsub, e);
1335bd0d90a5SMasatake YAMATO 		leaveSubparser ();
1336bd0d90a5SMasatake YAMATO 	}
1337bd0d90a5SMasatake YAMATO 	return q;
1338bd0d90a5SMasatake YAMATO }
1339bd0d90a5SMasatake YAMATO 
notifyReadFuncall(tokenInfo * const func,tokenInfo * const token,int parent)1340d1586adcSMasatake YAMATO static  int notifyReadFuncall (tokenInfo *const func,
1341d1586adcSMasatake YAMATO 							   tokenInfo *const token,
1342d1586adcSMasatake YAMATO 							   int parent)
1343d1586adcSMasatake YAMATO {
1344d1586adcSMasatake YAMATO 	int q = CORK_NIL;
1345d1586adcSMasatake YAMATO 	subparser *sub;
1346d1586adcSMasatake YAMATO 	foreachSubparser (sub, false)
1347d1586adcSMasatake YAMATO 	{
1348d1586adcSMasatake YAMATO 		rSubparser *rsub = (rSubparser *)sub;
1349d1586adcSMasatake YAMATO 		if (rsub->readFuncall)
1350d1586adcSMasatake YAMATO 		{
1351d1586adcSMasatake YAMATO 			enterSubparser (sub);
1352d1586adcSMasatake YAMATO 			q = rsub->readFuncall (rsub, func, token, parent);
1353d1586adcSMasatake YAMATO 			leaveSubparser ();
1354d1586adcSMasatake YAMATO 			if (q != CORK_NIL)
1355d1586adcSMasatake YAMATO 				break;
1356d1586adcSMasatake YAMATO 		}
1357d1586adcSMasatake YAMATO 	}
1358d1586adcSMasatake YAMATO 	return q;
1359d1586adcSMasatake YAMATO }
1360d1586adcSMasatake YAMATO 
findRTags(void)136125ec6aefSMasatake YAMATO static void findRTags (void)
136225ec6aefSMasatake YAMATO {
136325ec6aefSMasatake YAMATO 	tokenInfo *const token = newRToken ();
136425ec6aefSMasatake YAMATO 
1365ed1b6f16SMasatake YAMATO 	blackHoleIndex = makePlaceholder ("**BLACK-HOLE/DON'T TAG ME**");
1366ed1b6f16SMasatake YAMATO 	registerEntry (blackHoleIndex);
1367ed1b6f16SMasatake YAMATO 
1368ed1b6f16SMasatake YAMATO 	TRACE_PRINT ("install blackhole: %d", blackHoleIndex);
1369ed1b6f16SMasatake YAMATO 
137025ec6aefSMasatake YAMATO 	do
137125ec6aefSMasatake YAMATO 	{
137225ec6aefSMasatake YAMATO 		tokenRead(token);
137325ec6aefSMasatake YAMATO 		R_TRACE_TOKEN(token, CORK_NIL);
137405c79cb4SMasatake YAMATO 		parseStatement (token, CORK_NIL, false, false);
137525ec6aefSMasatake YAMATO 	}
137625ec6aefSMasatake YAMATO 	while (!tokenIsEOF (token));
137725ec6aefSMasatake YAMATO 
1378ed1b6f16SMasatake YAMATO 	TRACE_PRINT ("run blackhole", blackHoleIndex);
1379ed1b6f16SMasatake YAMATO 	markAllEntriesInScopeAsPlaceholder (blackHoleIndex);
1380ed1b6f16SMasatake YAMATO 
138125ec6aefSMasatake YAMATO 	tokenDelete (token);
1382ade07043SVitor Antunes }
1383ade07043SVitor Antunes 
initializeRParser(const langType language)138430fa30b1SMasatake YAMATO static void initializeRParser (const langType language)
138530fa30b1SMasatake YAMATO {
138630fa30b1SMasatake YAMATO 	Lang_R = language;
138730fa30b1SMasatake YAMATO }
138830fa30b1SMasatake YAMATO 
RParser(void)1389ade07043SVitor Antunes extern parserDefinition *RParser (void)
1390ade07043SVitor Antunes {
13919432553cSVitor Antunes 	static const char *const extensions[] = { "r", "R", "s", "q", NULL };
1392ade07043SVitor Antunes 	parserDefinition *const def = parserNew ("R");
1393ab3b3869SMasatake YAMATO 	static selectLanguage selectors[] = { selectByArrowOfR,
1394ab3b3869SMasatake YAMATO 										  NULL };
139525ec6aefSMasatake YAMATO 
1396ade07043SVitor Antunes 	def->extensions = extensions;
139709ae690fSMasatake YAMATO 	def->kindTable = RKinds;
139825ec6aefSMasatake YAMATO 	def->kindCount = ARRAY_SIZE(RKinds);
139925ec6aefSMasatake YAMATO 	def->fieldTable = RFields;
140025ec6aefSMasatake YAMATO 	def->fieldCount = ARRAY_SIZE (RFields);
140125ec6aefSMasatake YAMATO 	def->keywordTable = RKeywordTable;
140225ec6aefSMasatake YAMATO 	def->keywordCount = ARRAY_SIZE(RKeywordTable);
1403ed1b6f16SMasatake YAMATO 	def->useCork = CORK_QUEUE | CORK_SYMTAB;
140425ec6aefSMasatake YAMATO 	def->parser = findRTags;
1405ab3b3869SMasatake YAMATO 	def->selectLanguage = selectors;
140630fa30b1SMasatake YAMATO 	def->initialize = initializeRParser;
140725ec6aefSMasatake YAMATO 
1408ade07043SVitor Antunes 	return def;
1409ade07043SVitor Antunes }
141025ec6aefSMasatake YAMATO 
rExtractNameFromString(vString * str)14117852270eSMasatake YAMATO extern vString *rExtractNameFromString (vString* str)
14127852270eSMasatake YAMATO {
14137852270eSMasatake YAMATO 	int offset = 0;
14147852270eSMasatake YAMATO 
14157852270eSMasatake YAMATO 	if (vStringLength (str) == 0)
14167852270eSMasatake YAMATO 		return NULL;
14177852270eSMasatake YAMATO 
14187852270eSMasatake YAMATO 	char b = vStringChar (str, 0);
14197852270eSMasatake YAMATO 	if (b == '\'' || b == '"' || b == '`')
14207852270eSMasatake YAMATO 		offset = 1;
14217852270eSMasatake YAMATO 
14227852270eSMasatake YAMATO 	if (offset && vStringLength (str) < 3)
14237852270eSMasatake YAMATO 		return NULL;
14247852270eSMasatake YAMATO 
14257852270eSMasatake YAMATO 	vString *n = vStringNewInit (vStringValue (str) + offset);
14267852270eSMasatake YAMATO 	if (vStringChar (n, vStringLength (n) - 1) == b)
14277852270eSMasatake YAMATO 		vStringChop (n);
14287852270eSMasatake YAMATO 
14297852270eSMasatake YAMATO 	return n;
14307852270eSMasatake YAMATO }
14317852270eSMasatake YAMATO 
143225ec6aefSMasatake YAMATO #ifdef DEBUG
tokenTypeStr(enum RTokenType e)143325ec6aefSMasatake YAMATO static const char *tokenTypeStr(enum RTokenType e)
143425ec6aefSMasatake YAMATO { /* Generated by misc/enumstr.sh with cmdline:
143530fa30b1SMasatake YAMATO      parsers/r.c RTokenType tokenTypeStr TOKEN_R_ --use-lower-bits-as-is */
143625ec6aefSMasatake YAMATO 	switch (e)
143725ec6aefSMasatake YAMATO 	{
143830fa30b1SMasatake YAMATO 		case            TOKEN_R_EOF: return "EOF";
143930fa30b1SMasatake YAMATO 		case      TOKEN_R_UNDEFINED: return "UNDEFINED";
144030fa30b1SMasatake YAMATO 		case        TOKEN_R_KEYWORD: return "KEYWORD";
144130fa30b1SMasatake YAMATO 		case        TOKEN_R_NEWLINE: return "NEWLINE";
144230fa30b1SMasatake YAMATO 		case         TOKEN_R_NUMBER: return "NUMBER";
144330fa30b1SMasatake YAMATO 		case         TOKEN_R_SYMBOL: return "SYMBOL";
144430fa30b1SMasatake YAMATO 		case         TOKEN_R_STRING: return "STRING";
144530fa30b1SMasatake YAMATO 		case       TOKEN_R_OPERATOR: return "OPERATOR";
144630fa30b1SMasatake YAMATO 		case           TOKEN_R_DOTS: return "DOTS";
144730fa30b1SMasatake YAMATO 		case         TOKEN_R_DOTS_N: return "DOTS_N";
144830fa30b1SMasatake YAMATO 		case        TOKEN_R_LASSIGN: return "LASSIGN";
144930fa30b1SMasatake YAMATO 		case        TOKEN_R_RASSIGN: return "RASSIGN";
145030fa30b1SMasatake YAMATO 		case          TOKEN_R_SCOPE: return "SCOPE";
145125ec6aefSMasatake YAMATO 		default:                   break;
145225ec6aefSMasatake YAMATO 	}
145325ec6aefSMasatake YAMATO 	static char buf[3];
145425ec6aefSMasatake YAMATO 	if (isprint (e))
145525ec6aefSMasatake YAMATO 	{
145625ec6aefSMasatake YAMATO 		buf[0] = e;
145725ec6aefSMasatake YAMATO 		buf[1] = '\0';
145825ec6aefSMasatake YAMATO 	}
145925ec6aefSMasatake YAMATO 	else if (e == '\n')
146025ec6aefSMasatake YAMATO 	{
146125ec6aefSMasatake YAMATO 		buf[0] = '\\';
146225ec6aefSMasatake YAMATO 		buf[1] = 'n';
146325ec6aefSMasatake YAMATO 		buf[2] = '\0';
146425ec6aefSMasatake YAMATO 	}
146525ec6aefSMasatake YAMATO 	else
146625ec6aefSMasatake YAMATO 	{
146725ec6aefSMasatake YAMATO 		buf[0] = '\0';
146825ec6aefSMasatake YAMATO 	}
146925ec6aefSMasatake YAMATO 	return buf;
147025ec6aefSMasatake YAMATO }
147125ec6aefSMasatake YAMATO #endif
1472