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