From 27fe8a664dafa57f16ff797c0adb5ddee5e113ae Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Fri, 3 Nov 2023 02:15:52 +0900 Subject: [PATCH 1/6] main: make getSubparserLanguage visible to parsers Signed-off-by: Masatake YAMATO --- main/subparser.h | 1 + main/subparser_p.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/main/subparser.h b/main/subparser.h index 3ba6f7b25c..c148caa74f 100644 --- a/main/subparser.h +++ b/main/subparser.h @@ -62,6 +62,7 @@ extern subparser* getSubparserRunningBaseparser (void); extern void chooseExclusiveSubparser (subparser *s, void *data); extern subparser *getLanguageSubparser (langType sublang, bool including_none_crafted_parser); +extern langType getSubparserLanguage (subparser *s); /* Interface for Subparsers */ #define RUN_DEFAULT_SUBPARSERS -1 diff --git a/main/subparser_p.h b/main/subparser_p.h index 801e821c9b..375c6de188 100644 --- a/main/subparser_p.h +++ b/main/subparser_p.h @@ -25,7 +25,6 @@ * FUNCTION PROTOTYPES */ extern subparser *getFirstSubparser(struct slaveControlBlock *controlBlock); -extern langType getSubparserLanguage (subparser *s); /* A base parser doesn't have to call the following three functions. The main part calls them internally. */ From cd58e893a55d19d936a80bb20a7391c5df23bddc Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Fri, 3 Nov 2023 02:45:47 +0900 Subject: [PATCH 2/6] Yaml,refactor: move ypath code from OpenAPI subparser Signed-off-by: Masatake YAMATO --- parsers/openapi.c | 118 +++++-------------------------------- parsers/yaml.c | 120 +++++++++++++++++++++++++++++++++----- parsers/yaml.h | 21 ++++--- parsers/yamlfrontmatter.c | 91 +---------------------------- 4 files changed, 132 insertions(+), 218 deletions(-) diff --git a/parsers/openapi.c b/parsers/openapi.c index c57579375b..c3262a1967 100644 --- a/parsers/openapi.c +++ b/parsers/openapi.c @@ -12,15 +12,12 @@ */ #include "general.h" /* must always come first */ -#include "debug.h" #include "entry.h" #include "kind.h" #include "yaml.h" #include "parse.h" #include "subparser.h" -#include "keyword.h" #include "read.h" -#include "trace.h" typedef enum { @@ -43,126 +40,40 @@ static kindDefinition OpenAPIKinds [] = { { true, 'T', "tag", "tags"}, }; -/* - name: "THE NAME" */ -enum openapiDetectingState { - DSTAT_LAST_KEY, - DSTAT_LAST_VALUE, - DSTAT_INITIAL, -}; - - struct sOpenAPISubparser { yamlSubparser yaml; - enum openapiDetectingState detection_state; }; static tagYpathTable ypathTables [] = { { "paths/*", - DSTAT_LAST_KEY, KIND_PATH, }, + YPATH_DSTAT_LAST_KEY, KIND_PATH, }, { "components/responses/*", - DSTAT_LAST_KEY, KIND_RESPONSE, }, + YPATH_DSTAT_LAST_KEY, KIND_RESPONSE, }, { "responses/*", - DSTAT_LAST_KEY, KIND_RESPONSE, }, + YPATH_DSTAT_LAST_KEY, KIND_RESPONSE, }, { "components/parameters/*", - DSTAT_LAST_KEY, KIND_PARAMETER, }, + YPATH_DSTAT_LAST_KEY, KIND_PARAMETER, }, { "parameters/*", - DSTAT_LAST_KEY, KIND_PARAMETER, }, + YPATH_DSTAT_LAST_KEY, KIND_PARAMETER, }, { "components/schemas/*", - DSTAT_LAST_KEY, KIND_SCHEMA, }, + YPATH_DSTAT_LAST_KEY, KIND_SCHEMA, }, { "definitions/*", - DSTAT_LAST_KEY, KIND_SCHEMA, }, + YPATH_DSTAT_LAST_KEY, KIND_SCHEMA, }, { "info/title", - DSTAT_LAST_VALUE, KIND_TITLE, }, + YPATH_DSTAT_LAST_VALUE, KIND_TITLE, }, { "servers/*/url", - DSTAT_LAST_VALUE, KIND_SERVER, }, + YPATH_DSTAT_LAST_VALUE, KIND_SERVER, }, { "host", - DSTAT_LAST_VALUE, KIND_SERVER, }, + YPATH_DSTAT_LAST_VALUE, KIND_SERVER, }, { "tags/*/name", - DSTAT_LAST_VALUE, KIND_TAG, }, + YPATH_DSTAT_LAST_VALUE, KIND_TAG, }, }; -static void openapiStateMachine (struct sOpenAPISubparser *openapi, - yaml_token_t *token) -{ -#ifdef DO_TRACING - ypathPrintTypeStack (YAML(openapi)); -#endif - - switch (token->type) - { - case YAML_KEY_TOKEN: - openapi->detection_state = DSTAT_LAST_KEY; - break; - case YAML_SCALAR_TOKEN: - switch (openapi->detection_state) - { - case DSTAT_LAST_KEY: - ypathFillKeywordOfTokenMaybe (YAML(openapi), token, getInputLanguage ()); - /* FALL THROUGH */ - case DSTAT_LAST_VALUE: - TRACE_PRINT("token-callback: %s: %s", - (openapi->detection_state == DSTAT_LAST_KEY)? "key": "value", - (char*)token->data.scalar.value); - ypathHandleToken (YAML(openapi), token, openapi->detection_state, - ypathTables, ARRAY_SIZE (ypathTables)); - break; - default: - break; - } - - openapi->detection_state = DSTAT_INITIAL; - - break; - case YAML_VALUE_TOKEN: - openapi->detection_state = DSTAT_LAST_VALUE; - break; - - default: - openapi->detection_state = DSTAT_INITIAL; - break; - } -} - -static void newTokenCallback (yamlSubparser *s, yaml_token_t *token) -{ - if (token->type == YAML_BLOCK_SEQUENCE_START_TOKEN - || token->type == YAML_BLOCK_MAPPING_START_TOKEN) - ypathPushType (s, token); - - openapiStateMachine ((struct sOpenAPISubparser *)s, token); - - if (token->type == YAML_BLOCK_END_TOKEN) - ypathPopType (s); - else if (token->type == YAML_STREAM_END_TOKEN) - ypathPopAllTypes (s); -} - -static void inputStart(subparser *s) -{ - ((struct sOpenAPISubparser*)s)->detection_state = DSTAT_INITIAL; -} - -static void inputEnd(subparser *s) -{ - Assert (((yamlSubparser*)s)->ypathTypeStack == NULL); -} - static void findOpenAPITags (void) { scheduleRunningBaseparser (0); } -static void initialize (langType language) -{ - ypathCompileTables (language, ypathTables, ARRAY_SIZE (ypathTables), 0); -} - -static void finalize (langType language, bool initialized) -{ - if (initialized) - ypathCompiledCodeDelete (ypathTables, ARRAY_SIZE (ypathTables)); -} - extern parserDefinition* OpenAPIParser (void) { static const char *const patterns [] = { "openapi.yaml", NULL }; @@ -170,10 +81,9 @@ extern parserDefinition* OpenAPIParser (void) .yaml = { .subparser = { .direction = SUBPARSER_BI_DIRECTION, - .inputStart = inputStart, - .inputEnd = inputEnd, }, - .newTokenNotfify = newTokenCallback + .ypathTables = ypathTables, + .ypathTableCount = ARRAY_SIZE (ypathTables), }, }; static parserDependency dependencies [] = { @@ -190,7 +100,5 @@ extern parserDefinition* OpenAPIParser (void) def->kindTable = OpenAPIKinds; def->kindCount = ARRAY_SIZE (OpenAPIKinds); def->parser = findOpenAPITags; - def->initialize = initialize; - def->finalize = finalize; return def; } diff --git a/parsers/yaml.c b/parsers/yaml.c index 6dca9c5405..3f445dade3 100644 --- a/parsers/yaml.c +++ b/parsers/yaml.c @@ -123,6 +123,96 @@ static void handlYamlToken (yaml_token_t *token) } } +static int ypathCompileTable (langType language, tagYpathTable *table, int keywordId); +static void ypathCompileTables (langType language, tagYpathTable tables[], size_t count, int keywordId); +static void ypathCompiledCodeDelete (tagYpathTable tables[], size_t count); + +static void ypathHandleToken (yamlSubparser *yaml, yaml_token_t *token, int state, tagYpathTable tables[], size_t count); + +static void ypathPushType (yamlSubparser *yaml, yaml_token_t *token); +static void ypathPopType (yamlSubparser *yaml); +static void ypathPopAllTypes (yamlSubparser *yaml); +static void ypathFillKeywordOfTokenMaybe (yamlSubparser *yaml, yaml_token_t *token, langType lang); + +static void ypathDefaultStateMachine (yamlSubparser *s, yaml_token_t *token) +{ +#ifdef DO_TRACING + ypathPrintTypeStack (s); +#endif + + switch (token->type) + { + case YAML_KEY_TOKEN: + s->detectionState = YPATH_DSTAT_LAST_KEY; + break; + case YAML_SCALAR_TOKEN: + switch (s->detectionState) + { + case YPATH_DSTAT_LAST_KEY: + ypathFillKeywordOfTokenMaybe (s, token, getInputLanguage ()); + /* FALL THROUGH */ + case YPATH_DSTAT_LAST_VALUE: + TRACE_PRINT("token-callback: %s: %s", + (s->detectionState == YPATH_DSTAT_LAST_KEY)? "key": "value", + (char*)token->data.scalar.value); + ypathHandleToken (s, token, s->detectionState, + s->ypathTables, s->ypathTableCount); + break; + default: + break; + } + + s->detectionState = YPATH_DSTAT_INITIAL; + + break; + case YAML_VALUE_TOKEN: + s->detectionState = YPATH_DSTAT_LAST_VALUE; + break; + + default: + s->detectionState = YPATH_DSTAT_INITIAL; + break; + } +} + +static void ypathDefaultNewTokenCallback (yamlSubparser *s, yaml_token_t *token) +{ + if (token->type == YAML_BLOCK_SEQUENCE_START_TOKEN + || token->type == YAML_BLOCK_MAPPING_START_TOKEN) + ypathPushType (s, token); + + ypathDefaultStateMachine (s, token); + + if (token->type == YAML_BLOCK_END_TOKEN) + ypathPopType (s); + else if (token->type == YAML_STREAM_END_TOKEN) + ypathPopAllTypes (s); +} + +static void finiSubparserState (yamlSubparser *yaml) +{ + ypathCompiledCodeDelete (yaml->ypathTables, + yaml->ypathTableCount); + yaml->compiled = false; +} + +static void initSubparserState (yamlSubparser *yaml, langType sublang) +{ + yaml->ypathTypeStack = NULL; + yaml->detectionState = YPATH_DSTAT_INITIAL; + if (yaml->ypathTables && !yaml->compiled) + { + ypathCompileTables (sublang, yaml->ypathTables, + yaml->ypathTableCount, 0); + yaml->compiled = true; + + /* We cannot use the finalize method of the YAML parser for releasing + * the compiled code because foreachSubparser doesn't work in the + * method. In the context. We use the global trash instead. */ + DEFAULT_TRASH_BOX(yaml, finiSubparserState); + } +} + static void findYamlTags (void) { subparser *sub; @@ -132,15 +222,14 @@ static void findYamlTags (void) yamlInit (&yaml); - findRegexTags (); - foreachSubparser(sub, false) { - enterSubparser (sub); - ((yamlSubparser*)sub)->ypathTypeStack = NULL; - leaveSubparser (); + langType sublang = getSubparserLanguage(sub); + initSubparserState ((yamlSubparser*)sub, sublang); } + findRegexTags (); + sub = getSubparserRunningBaseparser(); if (sub) chooseExclusiveSubparser (sub, NULL); @@ -155,7 +244,10 @@ static void findYamlTags (void) foreachSubparser(sub, false) { enterSubparser (sub); - ((yamlSubparser *)sub)->newTokenNotfify ((yamlSubparser *)sub, &token); + if (((yamlSubparser *)sub)->newTokenNotfify) + ((yamlSubparser *)sub)->newTokenNotfify ((yamlSubparser *)sub, &token); + else + ypathDefaultNewTokenCallback ((yamlSubparser *)sub, &token); leaveSubparser (); } @@ -210,7 +302,7 @@ struct ypathTypeStack { struct ypathTypeStack *next; }; -extern int ypathCompileTable (langType language, tagYpathTable *table, int keywordId) +static int ypathCompileTable (langType language, tagYpathTable *table, int keywordId) { vString *tmpkey = vStringNew(); intArray *code = intArrayNew (); @@ -251,13 +343,13 @@ extern int ypathCompileTable (langType language, tagYpathTable *table, int keywo return keywordId; } -extern void ypathCompileTables (langType language, tagYpathTable tables[], size_t count, int keywordId) +static void ypathCompileTables (langType language, tagYpathTable tables[], size_t count, int keywordId) { for (size_t i = 0; i < count; i++) keywordId = ypathCompileTable (language, tables + i, keywordId); } -extern void ypathCompiledCodeDelete (tagYpathTable tables[], size_t count) +static void ypathCompiledCodeDelete (tagYpathTable tables[], size_t count) { for (size_t i = 0; i < count; i++) { @@ -266,7 +358,7 @@ extern void ypathCompiledCodeDelete (tagYpathTable tables[], size_t count) } } -extern void ypathPushType (yamlSubparser *yaml, yaml_token_t *token) +static void ypathPushType (yamlSubparser *yaml, yaml_token_t *token) { struct ypathTypeStack *s; @@ -279,7 +371,7 @@ extern void ypathPushType (yamlSubparser *yaml, yaml_token_t *token) s->key = KEYWORD_NONE; } -extern void ypathPopType (yamlSubparser *yaml) +static void ypathPopType (yamlSubparser *yaml) { struct ypathTypeStack *s; @@ -291,13 +383,13 @@ extern void ypathPopType (yamlSubparser *yaml) eFree (s); } -extern void ypathPopAllTypes (yamlSubparser *yaml) +static void ypathPopAllTypes (yamlSubparser *yaml) { while (yaml->ypathTypeStack) ypathPopType (yaml); } -extern void ypathFillKeywordOfTokenMaybe (yamlSubparser *yaml, yaml_token_t *token, langType lang) +static void ypathFillKeywordOfTokenMaybe (yamlSubparser *yaml, yaml_token_t *token, langType lang) { if (!yaml->ypathTypeStack) return; @@ -326,7 +418,7 @@ static bool ypathStateStackMatch (struct ypathTypeStack *stack, return false; } -extern void ypathHandleToken (yamlSubparser *yaml, yaml_token_t *token, int state, +static void ypathHandleToken (yamlSubparser *yaml, yaml_token_t *token, int state, tagYpathTable tables[], size_t count) { if (!yaml->ypathTypeStack) diff --git a/parsers/yaml.h b/parsers/yaml.h index 318c504989..c870195429 100644 --- a/parsers/yaml.h +++ b/parsers/yaml.h @@ -28,8 +28,18 @@ typedef struct sYamlSubparser yamlSubparser; struct sYamlSubparser { subparser subparser; void (* newTokenNotfify) (yamlSubparser *s, yaml_token_t *token); + struct sTagYpathTable *ypathTables; + size_t ypathTableCount; + + bool compiled; struct ypathTypeStack *ypathTypeStack; + enum ypathDetectingState { + YPATH_DSTAT_LAST_KEY, + YPATH_DSTAT_LAST_VALUE, + YPATH_DSTAT_INITIAL, + } detectionState; }; + #define YAML(S) ((yamlSubparser *)S) extern void attachYamlPosition (tagEntryInfo *tag, yaml_token_t *token, bool asEndPosition); @@ -49,16 +59,5 @@ typedef struct sTagYpathTable { void *code; /* YAML base parser private */ } tagYpathTable; -extern int ypathCompileTable (langType language, tagYpathTable *table, int keywordId); -extern void ypathCompileTables (langType language, tagYpathTable tables[], size_t count, int keywordId); -extern void ypathCompiledCodeDelete (tagYpathTable tables[], size_t count); - -extern void ypathHandleToken (yamlSubparser *yaml, yaml_token_t *token, int state, tagYpathTable tables[], size_t count); - -extern void ypathPushType (yamlSubparser *yaml, yaml_token_t *token); -extern void ypathPopType (yamlSubparser *yaml); -extern void ypathPopAllTypes (yamlSubparser *yaml); -extern void ypathFillKeywordOfTokenMaybe (yamlSubparser *yaml, yaml_token_t *token, langType lang); - extern void ypathPrintTypeStack(yamlSubparser *yaml); #endif diff --git a/parsers/yamlfrontmatter.c b/parsers/yamlfrontmatter.c index 35b40c507d..d3b196c2c2 100644 --- a/parsers/yamlfrontmatter.c +++ b/parsers/yamlfrontmatter.c @@ -21,25 +21,16 @@ #include "yaml.h" #include "entry.h" -#include "gcc-attr.h" #include "parse.h" #include "read.h" #include "subparser.h" -#include "trace.h" /* * DATA DECLARATIONS */ -enum yamlfrontmatterDetectingState { - DSTAT_LAST_KEY, - DSTAT_LAST_VALUE, - DSTAT_INITIAL, -}; - struct sYamlFrontMatterSubparser { yamlSubparser yaml; - enum yamlfrontmatterDetectingState detection_state; }; @@ -58,7 +49,7 @@ static langType frontMatterLang; static tagYpathTable ypathTables [] = { { "title", - DSTAT_LAST_VALUE, + YPATH_DSTAT_LAST_VALUE, .initTagEntry = yamlFrontmattterInitTagEntry, }, }; @@ -68,79 +59,12 @@ static tagYpathTable ypathTables [] = { * FUNCTION DEFINITIONS */ -static void yamlfrontmatterStateMachine (struct sYamlFrontMatterSubparser *yamlfrontmatter, - yaml_token_t *token) -{ -#ifdef DO_TRACING - ypathPrintTypeStack (YAML(yamlfrontmatter)); -#endif - - switch (token->type) - { - case YAML_KEY_TOKEN: - yamlfrontmatter->detection_state = DSTAT_LAST_KEY; - break; - case YAML_SCALAR_TOKEN: - switch (yamlfrontmatter->detection_state) - { - case DSTAT_LAST_KEY: - ypathFillKeywordOfTokenMaybe (YAML(yamlfrontmatter), token, getInputLanguage ()); - /* FALL THROUGH */ - case DSTAT_LAST_VALUE: - TRACE_PRINT("token-callback: %s: %s", - (yamlfrontmatter->detection_state == DSTAT_LAST_KEY)? "key": "value", - (char*)token->data.scalar.value); - ypathHandleToken (YAML(yamlfrontmatter), token, yamlfrontmatter->detection_state, - ypathTables, ARRAY_SIZE (ypathTables)); - break; - default: - break; - } - - yamlfrontmatter->detection_state = DSTAT_INITIAL; - - break; - case YAML_VALUE_TOKEN: - yamlfrontmatter->detection_state = DSTAT_LAST_VALUE; - break; - - default: - yamlfrontmatter->detection_state = DSTAT_INITIAL; - break; - } -} - -static void newTokenCallback (yamlSubparser *s, yaml_token_t *token) -{ - if (token->type == YAML_BLOCK_SEQUENCE_START_TOKEN - || token->type == YAML_BLOCK_MAPPING_START_TOKEN) - ypathPushType (s, token); - - yamlfrontmatterStateMachine ((struct sYamlFrontMatterSubparser *)s, token); - - if (token->type == YAML_BLOCK_END_TOKEN) - ypathPopType (s); - else if (token->type == YAML_STREAM_END_TOKEN) - ypathPopAllTypes (s); -} - static bool yamlFrontmattterInitTagEntry (tagEntryInfo *e, char *name, void * data CTAGS_ATTR_UNUSED) { initForeignTagEntry (e, name, frontMatterLang, FRONTMATTER_TITLE_KIND); return true; } -static void yamlFrontMatterInputStart(subparser *s) -{ - ((struct sYamlFrontMatterSubparser*)s)->detection_state = DSTAT_INITIAL; - ((yamlSubparser*)s)->ypathTypeStack = NULL; -} - -static void yamlFrontMatterInputEnd(subparser *s) -{ - Assert (((yamlSubparser*)s)->ypathTypeStack == NULL); -} - static void findYamlFrontMatterTags (void) { scheduleRunningBaseparser (0); @@ -148,26 +72,18 @@ static void findYamlFrontMatterTags (void) static void yamlFrontMatterInitialize (langType language) { - ypathCompileTables (language, ypathTables, ARRAY_SIZE (ypathTables), 0); frontMatterLang = getNamedLanguage ("FrontMatter", 0); } -static void yamlFrontMatterFinalize (langType language, bool initialized) -{ - if (initialized) - ypathCompiledCodeDelete (ypathTables, ARRAY_SIZE (ypathTables)); -} - extern parserDefinition* YamlFrontMatter (void) { static struct sYamlFrontMatterSubparser yamlfrontmatterSubparser = { .yaml = { .subparser = { .direction = SUBPARSER_SUB_RUNS_BASE, - .inputStart = yamlFrontMatterInputStart, - .inputEnd = yamlFrontMatterInputEnd, }, - .newTokenNotfify = newTokenCallback + .ypathTables = ypathTables, + .ypathTableCount = ARRAY_SIZE (ypathTables), }, }; static parserDependency dependencies [] = { @@ -184,7 +100,6 @@ extern parserDefinition* YamlFrontMatter (void) def->kindCount = 0; def->parser = findYamlFrontMatterTags; def->initialize = yamlFrontMatterInitialize; - def->finalize = yamlFrontMatterFinalize; /* This parser runs ONLY as a part of FrontMatter parser. * User may not want to enable/disable this parser directly. */ From 2477827a4f9e76419c4d7377ff6dad6121f6b2f0 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Fri, 3 Nov 2023 12:02:37 +0900 Subject: [PATCH 3/6] Yaml: add {enter,leave}BlockNotify methods to its sub parser interface Signed-off-by: Masatake YAMATO --- parsers/yaml.c | 22 ++++++++++++++-------- parsers/yaml.h | 4 ++++ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/parsers/yaml.c b/parsers/yaml.c index 3f445dade3..5e51bd686f 100644 --- a/parsers/yaml.c +++ b/parsers/yaml.c @@ -130,8 +130,8 @@ static void ypathCompiledCodeDelete (tagYpathTable tables[], size_t count); static void ypathHandleToken (yamlSubparser *yaml, yaml_token_t *token, int state, tagYpathTable tables[], size_t count); static void ypathPushType (yamlSubparser *yaml, yaml_token_t *token); -static void ypathPopType (yamlSubparser *yaml); -static void ypathPopAllTypes (yamlSubparser *yaml); +static void ypathPopType (yamlSubparser *yaml, yaml_token_t *token); +static void ypathPopAllTypes (yamlSubparser *yaml, yaml_token_t *token); static void ypathFillKeywordOfTokenMaybe (yamlSubparser *yaml, yaml_token_t *token, langType lang); static void ypathDefaultStateMachine (yamlSubparser *s, yaml_token_t *token) @@ -184,9 +184,9 @@ static void ypathDefaultNewTokenCallback (yamlSubparser *s, yaml_token_t *token) ypathDefaultStateMachine (s, token); if (token->type == YAML_BLOCK_END_TOKEN) - ypathPopType (s); + ypathPopType (s, token); else if (token->type == YAML_STREAM_END_TOKEN) - ypathPopAllTypes (s); + ypathPopAllTypes (s, token); } static void finiSubparserState (yamlSubparser *yaml) @@ -270,7 +270,7 @@ static void findYamlTags (void) foreachSubparser(sub, false) { enterSubparser (sub); - ypathPopAllTypes ((yamlSubparser*)sub); + ypathPopAllTypes ((yamlSubparser*)sub, NULL); leaveSubparser (); } @@ -369,12 +369,18 @@ static void ypathPushType (yamlSubparser *yaml, yaml_token_t *token) s->type = token->type; s->key = KEYWORD_NONE; + + if (yaml->enterBlockNotify) + yaml->enterBlockNotify (yaml, token); } -static void ypathPopType (yamlSubparser *yaml) +static void ypathPopType (yamlSubparser *yaml, yaml_token_t *token) { struct ypathTypeStack *s; + if (yaml->leaveBlockNotify) + yaml->leaveBlockNotify (yaml, token); + s = yaml->ypathTypeStack; yaml->ypathTypeStack = s->next; @@ -383,10 +389,10 @@ static void ypathPopType (yamlSubparser *yaml) eFree (s); } -static void ypathPopAllTypes (yamlSubparser *yaml) +static void ypathPopAllTypes (yamlSubparser *yaml, yaml_token_t *token) { while (yaml->ypathTypeStack) - ypathPopType (yaml); + ypathPopType (yaml, token); } static void ypathFillKeywordOfTokenMaybe (yamlSubparser *yaml, yaml_token_t *token, langType lang) diff --git a/parsers/yaml.h b/parsers/yaml.h index c870195429..7358a9d5f1 100644 --- a/parsers/yaml.h +++ b/parsers/yaml.h @@ -28,6 +28,10 @@ typedef struct sYamlSubparser yamlSubparser; struct sYamlSubparser { subparser subparser; void (* newTokenNotfify) (yamlSubparser *s, yaml_token_t *token); + + void (* enterBlockNotify) (yamlSubparser *s, yaml_token_t *token); + void (* leaveBlockNotify) (yamlSubparser *s, yaml_token_t *token); + struct sTagYpathTable *ypathTables; size_t ypathTableCount; From 13201a761873b66bbd9ebbecb659012a3b37f8f2 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Fri, 3 Nov 2023 12:21:08 +0900 Subject: [PATCH 4/6] Yaml: add ypathGetTypeStackDepth to the sub parser interface Signed-off-by: Masatake YAMATO --- parsers/yaml.c | 13 +++++++++++++ parsers/yaml.h | 1 + 2 files changed, 14 insertions(+) diff --git a/parsers/yaml.c b/parsers/yaml.c index 5e51bd686f..1fc1f05ce4 100644 --- a/parsers/yaml.c +++ b/parsers/yaml.c @@ -395,6 +395,19 @@ static void ypathPopAllTypes (yamlSubparser *yaml, yaml_token_t *token) ypathPopType (yaml, token); } +extern size_t ypathGetTypeStackDepth (yamlSubparser *yaml) +{ + size_t depth = 0; + struct ypathTypeStack *s = yaml->ypathTypeStack; + + while (s) { + depth++; + s = s->next; + } + + return depth; +} + static void ypathFillKeywordOfTokenMaybe (yamlSubparser *yaml, yaml_token_t *token, langType lang) { if (!yaml->ypathTypeStack) diff --git a/parsers/yaml.h b/parsers/yaml.h index 7358a9d5f1..b3d8252b4c 100644 --- a/parsers/yaml.h +++ b/parsers/yaml.h @@ -47,6 +47,7 @@ struct sYamlSubparser { #define YAML(S) ((yamlSubparser *)S) extern void attachYamlPosition (tagEntryInfo *tag, yaml_token_t *token, bool asEndPosition); +extern size_t ypathGetTypeStackDepth (yamlSubparser *yaml); /* * Experimental Ypath code From fe011ecca47636f5afce6bc1136d1daf8f399bae Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Fri, 3 Nov 2023 17:31:06 +0900 Subject: [PATCH 5/6] Yaml: add makeTagEntryNotifyViaYpath method to the sub parser interface Signed-off-by: Masatake YAMATO --- parsers/yaml.c | 4 +++- parsers/yaml.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/parsers/yaml.c b/parsers/yaml.c index 1fc1f05ce4..b7af6aa586 100644 --- a/parsers/yaml.c +++ b/parsers/yaml.c @@ -461,7 +461,9 @@ static void ypathHandleToken (yamlSubparser *yaml, yaml_token_t *token, int stat if (r) { attachYamlPosition (&tag, token, false); - makeTagEntry (&tag); + int index = makeTagEntry (&tag); + if (index != CORK_NIL && yaml->makeTagEntryNotifyViaYpath) + yaml->makeTagEntryNotifyViaYpath (yaml, index); } break; } diff --git a/parsers/yaml.h b/parsers/yaml.h index b3d8252b4c..dc31612f6e 100644 --- a/parsers/yaml.h +++ b/parsers/yaml.h @@ -31,6 +31,7 @@ struct sYamlSubparser { void (* enterBlockNotify) (yamlSubparser *s, yaml_token_t *token); void (* leaveBlockNotify) (yamlSubparser *s, yaml_token_t *token); + void (* makeTagEntryNotifyViaYpath) (yamlSubparser *s, int corkIndex); struct sTagYpathTable *ypathTables; size_t ypathTableCount; From 6e5576ab49bb2ffae87acc7d7c19f0d18fabf245 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Fri, 3 Nov 2023 17:36:51 +0900 Subject: [PATCH 6/6] AnsiblePlaybook: use the revised Ypath API Signed-off-by: Masatake YAMATO --- parsers/ansibleplaybook.c | 183 ++++++-------------------------------- 1 file changed, 27 insertions(+), 156 deletions(-) diff --git a/parsers/ansibleplaybook.c b/parsers/ansibleplaybook.c index e38e3d0913..a3aa642ceb 100644 --- a/parsers/ansibleplaybook.c +++ b/parsers/ansibleplaybook.c @@ -9,15 +9,12 @@ */ #include "general.h" /* must always come first */ -#include "debug.h" #include "entry.h" #include "kind.h" #include "yaml.h" #include "parse.h" #include "subparser.h" -#include - typedef enum { K_PLAY } ansiblePlaybookKind; @@ -26,176 +23,49 @@ static kindDefinition AnsiblePlaybookKinds [] = { { true, 'p', "play", "plays" }, }; -struct yamlBlockTypeStack { - yaml_token_type_t type; - int associatedCorkIndex; - struct yamlBlockTypeStack *next; -}; - -/* - name: "THE NAME" */ -enum ansiblePlaybookPlayDetectingState { - DSTAT_PLAY_NAME_INITIAL, - DSTAT_PLAY_NAME_KEY, - DSTAT_PLAY_NAME_KEY_SCALAR, - DSTAT_PLAY_NAME_VALUE, -}; - - struct sAnsiblePlaybookSubparser { yamlSubparser yaml; - struct yamlBlockTypeStack *type_stack; - enum ansiblePlaybookPlayDetectingState play_detection_state; + int nameIndex; }; -static void pushBlockType (struct sAnsiblePlaybookSubparser *ansible, yaml_token_type_t t) -{ - struct yamlBlockTypeStack *s; - - s = xMalloc (1, struct yamlBlockTypeStack); - - s->next = ansible->type_stack; - ansible->type_stack = s; - - s->type = t; - s->associatedCorkIndex = CORK_NIL; -} +static tagYpathTable ypathTables [] = { + { "*/name", + YPATH_DSTAT_LAST_VALUE, K_PLAY, }, +}; -static void popBlockType (struct sAnsiblePlaybookSubparser *ansible, - yaml_token_t *token) +static void +findAnsiblePlaybookTags (void) { - struct yamlBlockTypeStack *s; - - s = ansible->type_stack; - ansible->type_stack = s->next; - - s->next = NULL; - tagEntryInfo *tag = getEntryInCorkQueue (s->associatedCorkIndex); - if (tag && token) - attachYamlPosition (tag, token, true); - - eFree (s); + scheduleRunningBaseparser (0); } -static void popAllBlockType (struct sAnsiblePlaybookSubparser *ansible, - yaml_token_t *token) +static void inputStart(subparser *s) { - while (ansible->type_stack) - popBlockType (ansible, token); + ((struct sAnsiblePlaybookSubparser*)s)->nameIndex = CORK_NIL; } -static bool stateStackMatch (struct yamlBlockTypeStack *stack, - yaml_token_type_t *expectation, - unsigned int length, - bool partial) +static void makeTagEntryCallbackViaYpath(yamlSubparser *s, int corkIndex) { - if (length == 0) - { - if (stack == NULL) - return true; - else if (partial) - return true; - else - return false; - } - - if (stack == NULL) - return false; - - if (stack->type == expectation[0]) - return stateStackMatch (stack->next, expectation + 1, length - 1, partial); - else - return false; + /* a mapping in a sequence */ + if (ypathGetTypeStackDepth(s) == 2) + ((struct sAnsiblePlaybookSubparser *)s)->nameIndex = corkIndex; } -static bool scalarNeq (yaml_token_t *token, unsigned int len, const char* val) +static void leaveBlockCallback(yamlSubparser *s, yaml_token_t *token) { - if ((token->data.scalar.length == len) - && (strncmp (val, (char *)token->data.scalar.value, len) == 0)) - return true; - else - return false; -} - -static void ansiblePlaybookPlayStateMachine (struct sAnsiblePlaybookSubparser *ansible, - yaml_token_t *token) -{ - yaml_token_type_t play_expect[] = { - YAML_BLOCK_MAPPING_START_TOKEN, - YAML_BLOCK_SEQUENCE_START_TOKEN, - }; + struct sAnsiblePlaybookSubparser *ansible = (struct sAnsiblePlaybookSubparser *)s; - switch (token->type) + if (token + && ansible->nameIndex != CORK_NIL + && ypathGetTypeStackDepth(s) == 2) { - case YAML_KEY_TOKEN: - if (stateStackMatch (ansible->type_stack, - play_expect, ARRAY_SIZE (play_expect), - false)) - ansible->play_detection_state = DSTAT_PLAY_NAME_KEY; - else - ansible->play_detection_state = DSTAT_PLAY_NAME_INITIAL; - break; - case YAML_SCALAR_TOKEN: - if ((ansible->play_detection_state == DSTAT_PLAY_NAME_KEY) - && scalarNeq (token, 4, "name")) - ansible->play_detection_state = DSTAT_PLAY_NAME_KEY_SCALAR; - else if (ansible->play_detection_state == DSTAT_PLAY_NAME_VALUE) - { - tagEntryInfo tag; - initTagEntry (&tag, (char *)token->data.scalar.value, - K_PLAY); - attachYamlPosition (&tag, token, false); - - Assert (ansible->type_stack->associatedCorkIndex == CORK_NIL); - ansible->type_stack->associatedCorkIndex = makeTagEntry (&tag); - ansible->play_detection_state = DSTAT_PLAY_NAME_INITIAL; - } - else - ansible->play_detection_state = DSTAT_PLAY_NAME_INITIAL; - break; - case YAML_VALUE_TOKEN: - if (ansible->play_detection_state == DSTAT_PLAY_NAME_KEY_SCALAR) - ansible->play_detection_state = DSTAT_PLAY_NAME_VALUE; - else - ansible->play_detection_state = DSTAT_PLAY_NAME_INITIAL; - break; - default: - ansible->play_detection_state = DSTAT_PLAY_NAME_INITIAL; - break; + tagEntryInfo *tag = getEntryInCorkQueue (ansible->nameIndex); + if (tag) + attachYamlPosition (tag, token, true); + ansible->nameIndex = CORK_NIL; } } -static void newTokenCallback (yamlSubparser *s, yaml_token_t *token) -{ - if (token->type == YAML_BLOCK_SEQUENCE_START_TOKEN - || token->type == YAML_BLOCK_MAPPING_START_TOKEN) - pushBlockType ((struct sAnsiblePlaybookSubparser *)s, token->type); - - ansiblePlaybookPlayStateMachine ((struct sAnsiblePlaybookSubparser *)s, token); - - if (token->type == YAML_BLOCK_END_TOKEN) - popBlockType ((struct sAnsiblePlaybookSubparser *)s, token); - else if (token->type == YAML_STREAM_END_TOKEN) - popAllBlockType ((struct sAnsiblePlaybookSubparser *)s, token); -} - -static void inputStart(subparser *s) -{ - ((struct sAnsiblePlaybookSubparser*)s)->play_detection_state = DSTAT_PLAY_NAME_INITIAL; - ((struct sAnsiblePlaybookSubparser*)s)->type_stack = NULL; -} - -static void inputEnd(subparser *s) -{ - popAllBlockType ((struct sAnsiblePlaybookSubparser *)s, NULL); - Assert (((struct sAnsiblePlaybookSubparser*)s)->type_stack == NULL); -} - -static void -findAnsiblePlaybookTags (void) -{ - scheduleRunningBaseparser (0); -} - extern parserDefinition* AnsiblePlaybookParser (void) { static struct sAnsiblePlaybookSubparser ansiblePlaybookSubparser = { @@ -203,9 +73,11 @@ extern parserDefinition* AnsiblePlaybookParser (void) .subparser = { .direction = SUBPARSER_BI_DIRECTION, .inputStart = inputStart, - .inputEnd = inputEnd, }, - .newTokenNotfify = newTokenCallback + .ypathTables = ypathTables, + .ypathTableCount = ARRAY_SIZE (ypathTables), + .leaveBlockNotify = leaveBlockCallback, + .makeTagEntryNotifyViaYpath = makeTagEntryCallbackViaYpath, }, }; static parserDependency dependencies [] = { @@ -221,7 +93,6 @@ extern parserDefinition* AnsiblePlaybookParser (void) def->kindTable = AnsiblePlaybookKinds; def->kindCount = ARRAY_SIZE (AnsiblePlaybookKinds); def->parser = findAnsiblePlaybookTags; - def->useCork = CORK_QUEUE; return def; }