From ca0f6cbb446bec66ecddda7eea3cbc528fef2984 Mon Sep 17 00:00:00 2001 From: AllyDale Date: Wed, 17 Mar 2021 11:03:11 +0800 Subject: [PATCH] normalize syntax define --- README.md | 10 +- gpg_test.go | 72 +++++++++++++ regexp.go | 71 ------------- replace_list.go | 2 +- syntax.go | 176 +++++++++++++++++++++++++++---- regexp_test.go => syntax_test.go | 0 6 files changed, 233 insertions(+), 98 deletions(-) rename regexp_test.go => syntax_test.go (100%) diff --git a/README.md b/README.md index de27dbf..8e852af 100644 --- a/README.md +++ b/README.md @@ -171,7 +171,7 @@ Site : [https://github.com/vipally](https://github.com/vipally) #GOGP_GPGCFG() ``` - "**replace**" syntax -``` +```go **** -> , literal replacement**** // #GOGP_REPLACE(, ) ``` @@ -193,21 +193,21 @@ Site : [https://github.com/vipally](https://github.com/vipally) // #GOGP_GPONLY_END ``` - "**file-begin**" syntax -``` +```go // #GOGP_FILE_BEGIN ``` - "**file-end**" syntax -``` +```go // #GOGP_FILE_END ``` - "**once**" syntax -``` +```go // #GOGP_ONCE {only generate once from a gp file} // #GOGP_END_ONCE ``` - "**comment**" syntax -``` +```go //#GOGP_COMMENT {comment(in line) content} ``` diff --git a/gpg_test.go b/gpg_test.go index d4c94ad..e2f2d18 100644 --- a/gpg_test.go +++ b/gpg_test.go @@ -283,3 +283,75 @@ tail fmt.Println("rep", rep) rep = rep } + +/* +// // to remove code + + // // // #GOGP_COMMENT + // expTxtGogpComment = `(?sm:(?P/{2,}[ |\t]*#GOGP_COMMENT))` + + // //generic-programming flag + // expTxtTodoReplace = `(?P

.?)(?P\<[[:alpha:]_][[:word:]]*\>)(?P.?)` + + // // ignore all text format: + // // //#GOGP_IGNORE_BEGIN //#GOGP_IGNORE_END + // expTxtIgnore = `(?sm:\s*//#GOGP_IGNORE_BEGIN(?P.*?)(?://)??#GOGP_IGNORE_END.*?$[\r|\n]*)` + // expTxtGPOnly = `(?sm:\s*//#GOGP_GPONLY_BEGIN(?P.*?)(?://)??#GOGP_GPONLY_END.*?$[\r|\n]*)` + + // // select by condition defines in gpg file: + // // //#GOGP_IFDEF //#GOGP_ELSE //#GOGP_ENDIF + // // " || ! || == xxx || != xxx" + // expTxtIf = `(?sm:^(?:[ |\t]*/{2,}[ |\t]*)#GOGP_IFDEF[ |\t]+(?P[[:word:]<>\|!= \t]+)(?:.*?$[\r|\n]?)(?P.*?)(?:(?:[ |\t]*/{2,}[ |\t]*)#GOGP_ELSE(?:.*?$[\r|\n]?)[\r|\n]*(?P.*?))?(?:[ |\t]*/{2,}[ |\t]*)#GOGP_ENDIF.*?$[\r|\n]?)` + // expTxtIf2 = `(?sm:^(?:[ |\t]*/{2,}[ |\t]*)#GOGP_IFDEF2[ |\t]+(?P[[:word:]<>\|!= \t]+)(?:.*?$[\r|\n]?)(?P.*?)(?:(?:[ |\t]*/{2,}[ |\t]*)#GOGP_ELSE2(?:.*?$[\r|\n]?)[\r|\n]*(?P.*?))?(?:[ |\t]*/{2,}[ |\t]*)#GOGP_ENDIF2.*?$[\r|\n]?)` + + // // " || ! || == xxx || != xxx " + // // [] [] + // expCondition = `(?sm:^[ |\t]*(?P!)?[ |\t]*(?P[[:word:]<>]+)[ |\t]*(?:(?P==|!=)[ |\t]*(?P[[:word:]]+))?[ |\t]*)` + + // //#GOGP_SWITCH [] #GOGP_GOGP_ENDSWITCH + // expTxtSwitch = `(?sm:(?:^[ |\t]*/{2,}[ |\t]*)(?:#GOGP_SWITCH)(?:[ |\t]+(?P[[:word:]<>]+))?(?:[ |\t]*?.*?$)[\r|\n]*(?P.*?)(?:^[ |\t]*/{2,}[ |\t]*)#GOGP_ENDSWITCH.*?$[\r|\n]?)` + + // //#GOGP_CASE #GOGP_ENDCASE + // //#GOGP_DEFAULT #GOGP_ENDCASE + // expTxtCase = `(?sm:(?:^[ |\t]*/{2,}[ |\t]*)(?:(?:#GOGP_CASE[ |\t]+(?P[[:word:]<>\|!]+))|(?:#GOGP_DEFAULT))(?:[ |\t]*?.*?$)[\r|\n]*(?P.*?)(?:^[ |\t]*/{2,}[ |\t]*)#GOGP_ENDCASE.*?$[\r|\n]*)` + + // // require another gp file: + // // //#GOGP_REQUIRE( [, ]) + // expTxtRequire = `(?sm:\s*(?P^[ |\t]*(?://)?#GOGP_REQUIRE\((?P[^\n\r,]*?)(?:[ |\t]*?,[ |\t]*?(?:(?P[[:word:]|#|@]*)|#GOGP_GPGCFG\((?P[[:word:]]+)\)))??(?:[ |\t]*?\))).*?$[\r|\n]*(?:(?://#GOGP_IGNORE_BEGIN )?///require begin from\([^\n\r,]*?\)(?P.*?)(?://)?(?:#GOGP_IGNORE_END )?///require end from\([^\n\r,]*?\))?[\r|\n]*)` + // expTxtEmptyLine = `(?sm:(?P[\r|\n]{3,}))` + + // //must be "-sm", otherwise it with will repeat every line + // expTxtTrimEmptyLine = `(?-sm:^[\r|\n]*(?P.*?)[\r|\n]*$)` + + // // get gpg config string: + // // #GOGP_GPGCFG() + // expTxtGetGpgCfg = `(?sm:(?://)?#GOGP_GPGCFG\((?P[[:word:]]+)\))` + + // // #GOGP_REPLACE(,) + // expTxtReplaceKey = `(?sm:(?:^[ |\t]*/{2,}[ |\t]*)#GOGP_REPLACE\((?P\S+)[ |\t]*,[ |\t]*(?P\S+)\))` + // expTxtMapKey = `(?sm:(?:^[ |\t]*/{2,}[ |\t]*)#GOGP_MAP\((?P\S+)[ |\t]*,[ |\t]*(?P\S+)\))` + + // //remove "*" from value type such as "*string -> string" + // // #GOGP_RAWNAME() + // //gsExpTxtRawName = "(?-sm:(?://)?#GOGP_RAWNAME\((?P\S+)\))" + + // // only generate once from a gp file: + // // //#GOGP_ONCE //#GOGP_END_ONCE + // expTxtOnce = `(?sm:(?:^[ |\t]*/{2,}[ |\t]*)//#GOGP_ONCE(?:[ |\t]*?//.*?$)?[\r|\n]*(?P.*?)[\r|\n]*[ |\t]*?(?://)??#GOGP_END_ONCE.*?$[\r|\n]*)` + + // expTxtFileBegin = `(?sm:\s*(?P//#GOGP_FILE_BEGIN(?:[ |\t]+(?P[[:word:]]+))?).*?$[\r|\n]*(?://#GOGP_IGNORE_BEGIN ///gogp_file_begin.*?(?://)?#GOGP_IGNORE_END ///gogp_file_begin.*?$)?[\r|\n]*)` + // expTxtFileEnd = `(?sm:\s*(?P//#GOGP_FILE_END).*?$[\r|\n]*(?://#GOGP_IGNORE_BEGIN ///gogp_file_end.*?(?://)?#GOGP_IGNORE_END ///gogp_file_end.*?$)?[\r|\n]*)` + + // gogpExpTodoReplace = regexp.MustCompile(expTxtTodoReplace) + // gogpExpPretreatAll = regexp.MustCompile(fmt.Sprintf("%s|%s|%s|%s|%s|%s", expTxtIgnore, expTxtRequire, expTxtGetGpgCfg, expTxtOnce, expTxtReplaceKey, expTxtGogpComment)) + // gogpExpIgnore = regexp.MustCompile(expTxtIgnore) + // gogpExpCodeSelector = regexp.MustCompile(fmt.Sprintf("%s|%s|%s|%s|%s|%s", expTxtIgnore, expTxtGPOnly, expTxtIf, expTxtIf2, expTxtMapKey, expTxtSwitch)) + // gogpExpCases = regexp.MustCompile(expTxtCase) + // gogpExpEmptyLine = regexp.MustCompile(expTxtEmptyLine) + // gogpExpTrimEmptyLine = regexp.MustCompile(expTxtTrimEmptyLine) + // gogpExpRequire = regexp.MustCompile(expTxtRequire) + // gogpExpRequireAll = regexp.MustCompile(fmt.Sprintf("%s|%s|%s", expTxtRequire, expTxtFileBegin, expTxtFileEnd)) + // gogpExpReverseIgnoreAll = regexp.MustCompile(fmt.Sprintf("%s|%s|%s", expTxtFileBegin, expTxtFileEnd, expTxtIgnore)) + // gogpExpCondition = regexp.MustCompile(expTxtRequire) + // gogpExpComment = regexp.MustCompile(expTxtGogpComment) + */ diff --git a/regexp.go b/regexp.go index 3f29b58..fb1d9ab 100644 --- a/regexp.go +++ b/regexp.go @@ -28,9 +28,6 @@ package gogp import ( - "bytes" - "fmt" - "regexp" "strings" ) @@ -47,61 +44,6 @@ const ( rawKeyKeyType = "KEY_TYPE" //key_type rawKeyValueType = "VALUE_TYPE" //value_type - // // #GOGP_COMMENT - expTxtGogpComment = `(?sm:(?P/{2,}[ |\t]*#GOGP_COMMENT))` - - //generic-programming flag - expTxtTodoReplace = `(?P

.?)(?P\<[[:alpha:]_][[:word:]]*\>)(?P.?)` - - // ignore all text format: - // //#GOGP_IGNORE_BEGIN //#GOGP_IGNORE_END - expTxtIgnore = `(?sm:\s*//#GOGP_IGNORE_BEGIN(?P.*?)(?://)??#GOGP_IGNORE_END.*?$[\r|\n]*)` - expTxtGPOnly = `(?sm:\s*//#GOGP_GPONLY_BEGIN(?P.*?)(?://)??#GOGP_GPONLY_END.*?$[\r|\n]*)` - - // select by condition defines in gpg file: - // //#GOGP_IFDEF //#GOGP_ELSE //#GOGP_ENDIF - // " || ! || == xxx || != xxx" - expTxtIf = `(?sm:^(?:[ |\t]*/{2,}[ |\t]*)#GOGP_IFDEF[ |\t]+(?P[[:word:]<>\|!= \t]+)(?:.*?$[\r|\n]?)(?P.*?)(?:(?:[ |\t]*/{2,}[ |\t]*)#GOGP_ELSE(?:.*?$[\r|\n]?)[\r|\n]*(?P.*?))?(?:[ |\t]*/{2,}[ |\t]*)#GOGP_ENDIF.*?$[\r|\n]?)` - expTxtIf2 = `(?sm:^(?:[ |\t]*/{2,}[ |\t]*)#GOGP_IFDEF2[ |\t]+(?P[[:word:]<>\|!= \t]+)(?:.*?$[\r|\n]?)(?P.*?)(?:(?:[ |\t]*/{2,}[ |\t]*)#GOGP_ELSE2(?:.*?$[\r|\n]?)[\r|\n]*(?P.*?))?(?:[ |\t]*/{2,}[ |\t]*)#GOGP_ENDIF2.*?$[\r|\n]?)` - - // " || ! || == xxx || != xxx " - // [] [] - expCondition = `(?sm:^[ |\t]*(?P!)?[ |\t]*(?P[[:word:]<>]+)[ |\t]*(?:(?P==|!=)[ |\t]*(?P[[:word:]]+))?[ |\t]*)` - - //#GOGP_SWITCH [] #GOGP_GOGP_ENDSWITCH - expTxtSwitch = `(?sm:(?:^[ |\t]*/{2,}[ |\t]*)(?:#GOGP_SWITCH)(?:[ |\t]+(?P[[:word:]<>]+))?(?:[ |\t]*?.*?$)[\r|\n]*(?P.*?)(?:^[ |\t]*/{2,}[ |\t]*)#GOGP_ENDSWITCH.*?$[\r|\n]?)` - - //#GOGP_CASE #GOGP_ENDCASE - //#GOGP_DEFAULT #GOGP_ENDCASE - expTxtCase = `(?sm:(?:^[ |\t]*/{2,}[ |\t]*)(?:(?:#GOGP_CASE[ |\t]+(?P[[:word:]<>\|!]+))|(?:#GOGP_DEFAULT))(?:[ |\t]*?.*?$)[\r|\n]*(?P.*?)(?:^[ |\t]*/{2,}[ |\t]*)#GOGP_ENDCASE.*?$[\r|\n]*)` - - // require another gp file: - // //#GOGP_REQUIRE( [, ]) - expTxtRequire = `(?sm:\s*(?P^[ |\t]*(?://)?#GOGP_REQUIRE\((?P[^\n\r,]*?)(?:[ |\t]*?,[ |\t]*?(?:(?P[[:word:]|#|@]*)|#GOGP_GPGCFG\((?P[[:word:]]+)\)))??(?:[ |\t]*?\))).*?$[\r|\n]*(?:(?://#GOGP_IGNORE_BEGIN )?///require begin from\([^\n\r,]*?\)(?P.*?)(?://)?(?:#GOGP_IGNORE_END )?///require end from\([^\n\r,]*?\))?[\r|\n]*)` - expTxtEmptyLine = `(?sm:(?P[\r|\n]{3,}))` - - //must be "-sm", otherwise it with will repeat every line - expTxtTrimEmptyLine = `(?-sm:^[\r|\n]*(?P.*?)[\r|\n]*$)` - - // get gpg config string: - // #GOGP_GPGCFG() - expTxtGetGpgCfg = `(?sm:(?://)?#GOGP_GPGCFG\((?P[[:word:]]+)\))` - - // #GOGP_REPLACE(,) - expTxtReplaceKey = `(?sm:(?:^[ |\t]*/{2,}[ |\t]*)#GOGP_REPLACE\((?P\S+)[ |\t]*,[ |\t]*(?P\S+)\))` - expTxtMapKey = `(?sm:(?:^[ |\t]*/{2,}[ |\t]*)#GOGP_MAP\((?P\S+)[ |\t]*,[ |\t]*(?P\S+)\))` - - //remove "*" from value type such as "*string -> string" - // #GOGP_RAWNAME() - //gsExpTxtRawName = "(?-sm:(?://)?#GOGP_RAWNAME\((?P\S+)\))" - - // only generate once from a gp file: - // //#GOGP_ONCE //#GOGP_END_ONCE - expTxtOnce = `(?sm:(?:^[ |\t]*/{2,}[ |\t]*)//#GOGP_ONCE(?:[ |\t]*?//.*?$)?[\r|\n]*(?P.*?)[\r|\n]*[ |\t]*?(?://)??#GOGP_END_ONCE.*?$[\r|\n]*)` - - expTxtFileBegin = `(?sm:\s*(?P//#GOGP_FILE_BEGIN(?:[ |\t]+(?P[[:word:]]+))?).*?$[\r|\n]*(?://#GOGP_IGNORE_BEGIN ///gogp_file_begin.*?(?://)?#GOGP_IGNORE_END ///gogp_file_begin.*?$)?[\r|\n]*)` - expTxtFileEnd = `(?sm:\s*(?P//#GOGP_FILE_END).*?$[\r|\n]*(?://#GOGP_IGNORE_BEGIN ///gogp_file_end.*?(?://)?#GOGP_IGNORE_END ///gogp_file_end.*?$)?[\r|\n]*)` - // "//#GOGP_IGNORE_BEGIN ... //#GOGP_IGNORE_END" txtRequireResultFmt = "//#GOGP_IGNORE_BEGIN ///require begin from(%s)\n%s\n//#GOGP_IGNORE_END ///require end from(%s)" txtRequireAtResultFmt = "///require begin from(%s)\n%s\n///require end from(%s)" @@ -109,19 +51,6 @@ const ( ) var ( - gogpExpTodoReplace = regexp.MustCompile(expTxtTodoReplace) - gogpExpPretreatAll = regexp.MustCompile(fmt.Sprintf("%s|%s|%s|%s|%s|%s", expTxtIgnore, expTxtRequire, expTxtGetGpgCfg, expTxtOnce, expTxtReplaceKey, expTxtGogpComment)) - gogpExpIgnore = regexp.MustCompile(expTxtIgnore) - gogpExpCodeSelector = regexp.MustCompile(fmt.Sprintf("%s|%s|%s|%s|%s|%s", expTxtIgnore, expTxtGPOnly, expTxtIf, expTxtIf2, expTxtMapKey, expTxtSwitch)) - gogpExpCases = regexp.MustCompile(expTxtCase) - gogpExpEmptyLine = regexp.MustCompile(expTxtEmptyLine) - gogpExpTrimEmptyLine = regexp.MustCompile(expTxtTrimEmptyLine) - gogpExpRequire = regexp.MustCompile(expTxtRequire) - gogpExpRequireAll = regexp.MustCompile(fmt.Sprintf("%s|%s|%s", expTxtRequire, expTxtFileBegin, expTxtFileEnd)) - gogpExpReverseIgnoreAll = regexp.MustCompile(fmt.Sprintf("%s|%s|%s", expTxtFileBegin, expTxtFileEnd, expTxtIgnore)) - gogpExpCondition = regexp.MustCompile(expTxtRequire) - gogpExpComment = regexp.MustCompile(expTxtGogpComment) - txtFileBeginContent = `// /* //This line can be uncommented to disable all this file, and it doesn't effect to the .gp file // //If test or change .gp file required, comment it to modify and compile as normal go file diff --git a/replace_list.go b/replace_list.go index 1ae9f97..3039afe 100644 --- a/replace_list.go +++ b/replace_list.go @@ -117,7 +117,7 @@ func (this *replaceList) expString() (exp string) { exp = b.String() } else { //avoid return "", which will match every byte - exp = `\Q#GOGP_DO_NOT_HAVE_ANY_KEY#\E` + exp = `\Q#GOGP_DO_NOT_HAVE_ANY_REPLACE_KEY#\E` } //fmt.Println(exp) diff --git a/syntax.go b/syntax.go index c65baf9..dfa21ee 100644 --- a/syntax.go +++ b/syntax.go @@ -27,16 +27,24 @@ package gogp +import ( + "bytes" + "fmt" + "regexp" +) + var res = []*syntax{ &syntax{ - name: "comment", - usage: "make an in line comment in fake .go file.", - exp: `(?sm:(?P/{2,}[ |\t]*#GOGP_COMMENT))`, - syntax: `// #GOGP_COMMENT`, + name: "#comment", + usage: "make an in line comment in fake .go file.", + exp: `(?sm:(?P/{2,}[ |\t]*#GOGP_COMMENT))`, + syntax: ` +// #GOGP_COMMENT {expected code} +`, }, &syntax{ - name: "if", - usage: "", + name: "#if", + usage: "double-way branch selector by condition", exp: `(?sm:^(?:[ |\t]*/{2,}[ |\t]*)#GOGP_IFDEF[ |\t]+(?P[[:word:]<>\|!= \t]+)(?:.*?$[\r|\n]?)(?P.*?)(?:(?:[ |\t]*/{2,}[ |\t]*)#GOGP_ELSE(?:.*?$[\r|\n]?)[\r|\n]*(?P.*?))?(?:[ |\t]*/{2,}[ |\t]*)#GOGP_ENDIF.*?$[\r|\n]?)`, syntax: ` // #GOGP_IFDEF || ! || == xxx || != xxx @@ -51,8 +59,8 @@ var res = []*syntax{ `, }, &syntax{ - name: "switch", - usage: "", + name: "#switch", + usage: "multi-way branch selector by condition", exp: `(?sm:(?:^[ |\t]*/{2,}[ |\t]*)(?:#GOGP_SWITCH)(?:[ |\t]+(?P[[:word:]<>]+))?(?:[ |\t]*?.*?$)[\r|\n]*(?P.*?)(?:^[ |\t]*/{2,}[ |\t]*)#GOGP_ENDSWITCH.*?$[\r|\n]?)`, syntax: ` **** it is multi-switch logic(more than one case brantch can trigger out) **** @@ -67,8 +75,8 @@ var res = []*syntax{ `, }, &syntax{ - name: "case", - usage: "", + name: "#case", + usage: "branches of switch syntax", exp: `(?sm:(?:^[ |\t]*/{2,}[ |\t]*)(?:(?:#GOGP_CASE[ |\t]+(?P[[:word:]<>\|!]+))|(?:#GOGP_DEFAULT))(?:[ |\t]*?.*?$)[\r|\n]*(?P.*?)(?:^[ |\t]*/{2,}[ |\t]*)#GOGP_ENDCASE.*?$[\r|\n]*)`, syntax: ` // #GOGP_CASE || ! || == xxx || != xxx || || ! @@ -80,26 +88,117 @@ var res = []*syntax{ `, }, &syntax{ - name: "require", - usage: "", - exp: `(?sm:\s*(?P^[ |\t]*(?://)?#GOGP_REQUIRE\((?P[^\n\r,]*?)(?:[ |\t]*?,[ |\t]*?(?:(?P[[:word:]|#|@]*)|#GOGP_GPGCFG\((?P[[:word:]]+)\)))??(?:[ |\t]*?\))).*?$[\r|\n]*(?:(?://#GOGP_IGNORE_BEGIN )?///require begin from\([^\n\r,]*?\)(?P.*?)(?://)?(?:#GOGP_IGNORE_END )?///require end from\([^\n\r,]*?\))?[\r|\n]*)`, - syntax: `// #GOGP_REQUIRE( [, ])`, + name: "#require", + usage: "require another .gp file", + exp: `(?sm:\s*(?P^[ |\t]*(?://)?#GOGP_REQUIRE\((?P[^\n\r,]*?)(?:[ |\t]*?,[ |\t]*?(?:(?P[[:word:]|#|@]*)|#GOGP_GPGCFG\((?P[[:word:]]+)\)))??(?:[ |\t]*?\))).*?$[\r|\n]*(?:(?://#GOGP_IGNORE_BEGIN )?///require begin from\([^\n\r,]*?\)(?P.*?)(?://)?(?:#GOGP_IGNORE_END )?///require end from\([^\n\r,]*?\))?[\r|\n]*)`, + syntax: ` +// #GOGP_REQUIRE( [, ]) +`, }, &syntax{ - name: "replace", - exp: `(?sm:(?:^[ |\t]*/{2,}[ |\t]*)#GOGP_REPLACE\((?P\S+)[ |\t]*,[ |\t]*(?P\S+)\))`, + name: "#replace", + usage: "build-in key-value replace command for generating .gp file", + exp: `(?sm:(?:^[ |\t]*/{2,}[ |\t]*)#GOGP_REPLACE\((?P\S+)[ |\t]*,[ |\t]*(?P\S+)\))`, syntax: ` **** -> , literal replacement**** // #GOGP_REPLACE(, ) `, }, &syntax{ - name: "map", - usage: "", + name: "#map", + usage: "build-in key-value define for generating .gp file. Which can affect brantch of #if and #switch after this code.", exp: `(?sm:(?:^[ |\t]*/{2,}[ |\t]*)#GOGP_MAP\((?P\S+)[ |\t]*,[ |\t]*(?P\S+)\))`, syntax: ` **** -> , which can affect brantch of #GOGP_IFDEF and #GOGP_SWITCH after this code**** // #GOGP_MAP(, ) +`, + }, + &syntax{ + name: "#to-replace", + usage: "literal that waiting to replacing.", + exp: `(?P

.?)(?P\<[[:alpha:]_][[:word:]]*\>)(?P.?)`, + syntax: ` +<{to-replace}> +`, + }, + &syntax{ + name: "#ignore", + usage: "txt that will ignore by gogp tool.", + exp: `(?sm:\s*//#GOGP_IGNORE_BEGIN(?P.*?)(?://)??#GOGP_IGNORE_END.*?$[\r|\n]*)`, + syntax: ` +// #GOGP_IGNORE_BEGIN + {ignore-content} +// #GOGP_IGNORE_END +`, + }, + &syntax{ + name: "#gp-only", + usage: "txt that will stay at .gp file only. Which will ignored at final .go file.", + exp: `(?sm:\s*//#GOGP_GPONLY_BEGIN(?P.*?)(?://)??#GOGP_GPONLY_END.*?$[\r|\n]*)`, + syntax: ` +// #GOGP_GPONLY_BEGIN + {gp-only content} +// #GOGP_GPONLY_END +`, + }, + &syntax{ + name: "#condition", + usage: "txt that for #if or #case condition field parser.", + exp: `(?sm:^[ |\t]*(?P!)?[ |\t]*(?P[[:word:]<>]+)[ |\t]*(?:(?P==|!=)[ |\t]*(?P[[:word:]]+))?[ |\t]*)`, + syntax: ` + || ! || == xxx || != xxx || || ! +`, + }, + &syntax{ + name: "#empty-line", + usage: "empty line.", + exp: `(?sm:(?P[\r|\n]{3,}))`, + syntax: ` +{empty-lines} +`, + }, + &syntax{ + name: "#trim-empty-line", + usage: "trim empty line", + exp: `(?-sm:^[\r|\n]*(?P.*?)[\r|\n]*$)`, + syntax: ` +{empty-lines} +{contents} +{empty-lines} +`, + }, + &syntax{ + name: "#gpg-config", + usage: "refer .gpg config", + exp: `(?sm:(?://)?#GOGP_GPGCFG\((?P[[:word:]]+)\))`, + syntax: ` +[//]#GOGP_GPGCFG() +`, + }, + &syntax{ + name: "#once", + usage: "code that will generate once during one .gp file processing.", + exp: `(?sm:(?:^[ |\t]*/{2,}[ |\t]*)//#GOGP_ONCE(?:[ |\t]*?//.*?$)?[\r|\n]*(?P.*?)[\r|\n]*[ |\t]*?(?://)??#GOGP_END_ONCE.*?$[\r|\n]*)`, + syntax: ` +// #GOGP_ONCE + {only generate once from a gp file} +// #GOGP_END_ONCE +`, + }, + &syntax{ + name: "#file-begin", + usage: "file head of a fake .go file.", + exp: `(?sm:\s*(?P//#GOGP_FILE_BEGIN(?:[ |\t]+(?P[[:word:]]+))?).*?$[\r|\n]*(?://#GOGP_IGNORE_BEGIN ///gogp_file_begin.*?(?://)?#GOGP_IGNORE_END ///gogp_file_begin.*?$)?[\r|\n]*)`, + syntax: ` +// #GOGP_FILE_BEGIN +`, + }, + &syntax{ + name: "#file-end", + usage: "file tail of a fake .go file.", + exp: `(?sm:\s*(?P//#GOGP_FILE_END).*?$[\r|\n]*(?://#GOGP_IGNORE_BEGIN ///gogp_file_end.*?(?://)?#GOGP_IGNORE_END ///gogp_file_end.*?$)?[\r|\n]*)`, + syntax: ` +// #GOGP_FILE_END `, }, } @@ -112,9 +211,9 @@ type syntax struct { syntax string } -func regexpCompile(res ...*syntax) *regexp.Regexp { +func compileMultiRegexps(res ...*syntax) *regexp.Regexp { var b bytes.Buffer - var exp = `\Q#GOGP_DO_NOT_HAVE_ANY_KEY#\E` + var exp = `\Q#GOGP_DO_NOT_HAVE_ANY_REGEXP_SYNTAX#\E` if len(res) > 0 { for _, v := range res { b.WriteString(v.exp) @@ -122,7 +221,6 @@ func regexpCompile(res ...*syntax) *regexp.Regexp { } b.Truncate(b.Len() - 1) //remove last '|' exp = b.String() - } return regexp.MustCompile(exp) } @@ -140,3 +238,39 @@ func findRE(name string) *syntax { panic(fmt.Errorf("findRE(%s) not found", name)) return nil } + +var ( + gogpExpTodoReplace = findRE("#replace").Regexp() + gogpExpPretreatAll = compileMultiRegexps( + findRE("#ignore"), + findRE("#require"), + findRE("#gpg-config"), + findRE("#once"), + findRE("#replace"), + findRE("#comment"), + ) + gogpExpIgnore = findRE("#ignore").Regexp() + gogpExpCodeSelector = compileMultiRegexps( + findRE("#ignore"), + findRE("#gp-only"), + findRE("#map"), + findRE("#if"), + findRE("#switch"), + ) + gogpExpCases = findRE("#case").Regexp() + gogpExpEmptyLine = findRE("#empty-line").Regexp() + gogpExpTrimEmptyLine = findRE("#trim-empty-line").Regexp() + gogpExpRequire = findRE("#require").Regexp() + gogpExpRequireAll = compileMultiRegexps( + findRE("#require"), + findRE("#file-begin"), + findRE("#file-end"), + ) + gogpExpReverseIgnoreAll = compileMultiRegexps( + findRE("#file-begin"), + findRE("#file-end"), + findRE("#ignore"), + ) + gogpExpCondition = findRE("#condition").Regexp() + gogpExpComment = findRE("#comment").Regexp() +) diff --git a/regexp_test.go b/syntax_test.go similarity index 100% rename from regexp_test.go rename to syntax_test.go