From a0a9f1ef2124fdb3c2758ffe1edcf5981e03743a Mon Sep 17 00:00:00 2001 From: cedporter Date: Thu, 2 Jul 2020 17:46:04 -0400 Subject: [PATCH] SAS: Handle edge case of string macro functions (#2451) --- components/prism-sas.js | 16 +++- components/prism-sas.min.js | 2 +- .../sas/macro_string_function_feature.test | 88 +++++++++++++++++++ tests/languages/sas/macrokeyword_feature.test | 15 ++-- 4 files changed, 111 insertions(+), 10 deletions(-) create mode 100644 tests/languages/sas/macro_string_function_feature.test diff --git a/components/prism-sas.js b/components/prism-sas.js index ab04dac1bf..bb152e721f 100644 --- a/components/prism-sas.js +++ b/components/prism-sas.js @@ -237,7 +237,21 @@ lookbehind: true, inside: args }, - + 'macro-string-functions': { + pattern: /((?:^|\s|=))%(?:NRBQUOTE|NRQUOTE|NRSTR|BQUOTE|QUOTE|STR)\(.*?(?:[^%]\))/i, + lookbehind: true, + inside: { + 'function': { + pattern: /%(?:NRBQUOTE|NRQUOTE|NRSTR|BQUOTE|QUOTE|STR)/i, + alias: 'keyword' + }, + 'string': { + pattern: /(\()[^)]+/, + lookbehind: true + }, + 'punctuation': punctuation + } + }, /*Special keywords within macros*/ 'macro-keyword': { pattern: /((?:^|\s)=?)%(?:ABORT|BQUOTE|BY|CMS|COPY|DISPLAY|DO|ELSE|END|EVAL|GLOBAL|GO|GOTO|IF|INC|INCLUDE|INDEX|INPUT|KTRIM|LENGTH|LET|LIST|LOCAL|NRBQUOTE|NRQUOTE|NRSTR|PUT|QKTRIM|QSCAN|QSUBSTR|QSYSFUNC|QUOTE|QUPCASE|RETURN|RUN|SCAN|STR|SUBSTR|SUPERQ|SYMDEL|SYMGLOBL|SYMLOCAL|SYMEXIST|SYSCALL|SYSEVALF|SYSEXEC|SYSFUNC|SYSGET|SYSRPUT|THEN|TO|TSO|UNQUOTE|UNTIL|UPCASE|WHILE|WINDOW)\b/i, diff --git a/components/prism-sas.min.js b/components/prism-sas.min.js index c7e0a2f0fc..5659c4a19c 100644 --- a/components/prism-sas.min.js +++ b/components/prism-sas.min.js @@ -1 +1 @@ -!function(e){var t="(?:\"(?:\"\"|[^\"])*\"(?!\")|'(?:''|[^'])*'(?!'))",a=/\b(?:\d[\da-f]*x|\d+(?:\.\d+)?(?:e[+-]?\d+)?)\b/i,n={pattern:RegExp(t+"[bx]"),alias:"number"},i={pattern:/(^|\s+)(?:proc\s+\w+|quit|run|data(?!\=))\b/i,alias:"keyword",lookbehind:!0},s=[/\/\*[\s\S]*?\*\//,{pattern:/(^\s*|;\s*)\*[^;]*;/m,lookbehind:!0}],r={pattern:RegExp(t),greedy:!0},o=/[$%@.(){}\[\];,\\]/,l={pattern:/%?\w+(?=\()/,alias:"keyword"},c={function:l,"arg-value":{pattern:/(\s*=\s*)[A-Z\.]+/i,lookbehind:!0},operator:/=/,"macro-variable":{pattern:/&[^\.]*\./i,alias:"string"},arg:{pattern:/[A-Z]+/i,alias:"keyword"},number:a,"numeric-constant":n,punctuation:o,string:r},d={pattern:/\b(?:format|put)\b=?[\w'$.]+/im,inside:{keyword:/^(?:format|put)(?=\=)/i,equals:/=/,format:{pattern:/(?:\w|\$\d)+\.\d?/i,alias:"number"}}},p={pattern:/\b(?:format|put)\s+[\w']+(?:\s+[$.\w]+)+(?=;)/i,inside:{keyword:/^(?:format|put)/i,format:{pattern:/[\w$]+\.\d?/,alias:"number"}}},u={pattern:/((?:^|[\s])=?)(?:catname|checkpoint execute_always|dm|endsas|filename|footnote|%include|libname|%list|lock|missing|options|page|resetline|%run|sasfile|skip|sysecho|title\d?)\b/i,lookbehind:!0,alias:"keyword"},m={pattern:/(^|\s)(?:submit(?:\s+(?:load|parseonly|norun))?|endsubmit)\b/i,lookbehind:!0,alias:"keyword"},b="accessControl|cdm|aggregation|aStore|ruleMining|audio|autotune|bayesianNetClassifier|bioMedImage|boolRule|builtins|cardinality|sccasl|clustering|copula|countreg|dataDiscovery|dataPreprocess|dataSciencePilot|dataStep|decisionTree|deepLearn|deepNeural|varReduce|simSystem|ds2|deduplication|ecm|entityRes|espCluster|explainModel|factmac|fastKnn|fcmpact|fedSql|freqTab|gam|gleam|graphSemiSupLearn|gVarCluster|hiddenMarkovModel|hyperGroup|image|iml|ica|kernalPca|langModel|ldaTopic|sparseML|mlTools|mixed|modelPublishing|mbc|network|optNetwork|neuralNet|nonlinear|nmf|nonParametricBayes|optimization|panel|pls|percentile|pca|phreg|qkb|qlim|quantreg|recommend|tsReconcile|deepRnn|regression|reinforcementLearn|robustPca|sampling|sparkEmbeddedProcess|search(?:Analytics)?|sentimentAnalysis|sequence|configuration|session(?:Prop)?|severity|simple|smartData|sandwich|spatialreg|stabilityMonitoring|spc|loadStreams|svDataDescription|svm|table|conditionalRandomFields|text(?:Rule(?:Develop|Score)|Mining|Parse|Topic|Util|Filters|Frequency)|tsInfo|timeData|transpose|uniTimeSeries",g={pattern:RegExp("(^|\\s)(?:action\\s+)?(?:)\\.[a-z]+\\b[^;]+".replace(//g,function(){return b}),"i"),lookbehind:!0,inside:{keyword:RegExp("(?:)\\.[a-z]+\\b".replace(//g,function(){return b}),"i"),action:{pattern:/(?:action)/i,alias:"keyword"},comment:s,function:l,"arg-value":c["arg-value"],operator:c.operator,argument:c.arg,number:a,"numeric-constant":n,punctuation:o,string:r}},k={pattern:/((?:^|\s)=?)(?:after|analysis|and|array|barchart|barwidth|begingraph|by|call|cas|cbarline|cfill|class(?:lev)?|close|column|computed?|contains|continue|data(?=\=)|define|delete|describe|document|do\s+over|do|dol|drop|dul|end(?:source|comp)?|entryTitle|else|eval(?:uate)?|exec(?:ute)?|exit|fill(?:attrs)?|file(?:name)?|flist|fnc|function(?:list)?|goto|global|group(?:by)?|headline|headskip|histogram|if|infile|keep|keylabel|keyword|label|layout|leave|legendlabel|length|libname|loadactionset|merge|midpoints|name|noobs|nowd|_?null_|ods|options|or|otherwise|out(?:put)?|over(?:lay)?|plot|put|print|raise|ranexp|rannor|rbreak|retain|return|select|set|session|sessref|source|statgraph|sum|summarize|table|temp|terminate|then\s+do|then|title\d?|to|var|when|where|xaxisopts|yaxisopts|y2axisopts)\b/i,lookbehind:!0};e.languages.sas={datalines:{pattern:/^(\s*)(?:(?:data)?lines|cards);[\s\S]+?^\s*;/im,lookbehind:!0,alias:"string",inside:{keyword:{pattern:/^(?:(?:data)?lines|cards)/i},punctuation:/;/}},"proc-sql":{pattern:/(^proc\s+(?:fed)?sql(?:\s+[\w|=]+)?;)[\s\S]+?(?=^(?:proc\s+\w+|quit|run|data);|(?![\s\S]))/im,lookbehind:!0,inside:{sql:{pattern:RegExp("^[ \t]*(?:select|alter\\s+table|(?:create|describe|drop)\\s+(?:index|table(?:\\s+constraints)?|view)|create\\s+unique\\s+index|insert\\s+into|update)(?:|[^;\"'])+;".replace(//g,function(){return t}),"im"),alias:"language-sql",inside:e.languages.sql},"global-statements":u,"sql-statements":{pattern:/(^|\s)(?:disconnect\s+from|exec(?:ute)?|begin|commit|rollback|reset|validate)\b/i,lookbehind:!0,alias:"keyword"},number:a,"numeric-constant":n,punctuation:o,string:r}},"proc-groovy":{pattern:/(^proc\s+groovy(?:\s+[\w|=]+)?;)[\s\S]+?(?=^(?:proc\s+\w+|quit|run|data);|(?![\s\S]))/im,lookbehind:!0,inside:{comment:s,groovy:{pattern:RegExp("(^[ \t]*submit(?:\\s+(?:load|parseonly|norun))?)(?:|[^\"'])+?(?=endsubmit;)".replace(//g,function(){return t}),"im"),lookbehind:!0,alias:"language-groovy",inside:e.languages.groovy},keyword:k,"submit-statement":m,"global-statements":u,number:a,"numeric-constant":n,punctuation:o,string:r}},"proc-lua":{pattern:/(^proc\s+lua(?:\s+[\w|=]+)?;)[\s\S]+?(?=^(?:proc\s+\w+|quit|run|data);|(?![\s\S]))/im,lookbehind:!0,inside:{comment:s,lua:{pattern:RegExp("(^[ \t]*submit(?:\\s+(?:load|parseonly|norun))?)(?:|[^\"'])+?(?=endsubmit;)".replace(//g,function(){return t}),"im"),lookbehind:!0,alias:"language-lua",inside:e.languages.lua},keyword:k,"submit-statement":m,"global-statements":u,number:a,"numeric-constant":n,punctuation:o,string:r}},"proc-cas":{pattern:/(^proc\s+cas(?:\s+[\w|=]+)?;)[\s\S]+?(?=^(?:proc\s+\w+|quit|data);|(?![\s\S]))/im,lookbehind:!0,inside:{comment:s,"statement-var":{pattern:/((?:^|\s)=?)saveresult\s+[^;]+/im,lookbehind:!0,inside:{statement:{pattern:/^saveresult\s+\S+/i,inside:{keyword:/^(?:saveresult)/i}},rest:c}},"cas-actions":g,statement:{pattern:/((?:^|\s)=?)(?:default|(?:un)?set|on|output|upload)[^;]+/im,lookbehind:!0,inside:c},step:i,keyword:k,function:l,format:d,altformat:p,"global-statements":u,number:a,"numeric-constant":n,punctuation:o,string:r}},"proc-args":{pattern:RegExp("(^proc\\s+\\w+\\s+)(?!\\s)(?:[^;\"']|)+;".replace(//g,function(){return t}),"im"),lookbehind:!0,inside:c},"macro-keyword":{pattern:/((?:^|\s)=?)%(?:ABORT|BQUOTE|BY|CMS|COPY|DISPLAY|DO|ELSE|END|EVAL|GLOBAL|GO|GOTO|IF|INC|INCLUDE|INDEX|INPUT|KTRIM|LENGTH|LET|LIST|LOCAL|NRBQUOTE|NRQUOTE|NRSTR|PUT|QKTRIM|QSCAN|QSUBSTR|QSYSFUNC|QUOTE|QUPCASE|RETURN|RUN|SCAN|STR|SUBSTR|SUPERQ|SYMDEL|SYMGLOBL|SYMLOCAL|SYMEXIST|SYSCALL|SYSEVALF|SYSEXEC|SYSFUNC|SYSGET|SYSRPUT|THEN|TO|TSO|UNQUOTE|UNTIL|UPCASE|WHILE|WINDOW)\b/i,lookbehind:!0,alias:"keyword"},"macro-declaration":{pattern:/^%macro[^;]+(?=;)/im,inside:{keyword:/%macro/i}},"macro-end":{pattern:/^%mend[^;]+(?=;)/im,inside:{keyword:/%mend/i}},macro:{pattern:/%_\w+(?=\()/,alias:"keyword"},input:{pattern:/\binput\s+[-\w\s/*.$&]+;/i,inside:{input:{alias:"keyword",pattern:/^input/i},comment:s,number:a,"numeric-constant":n}},"options-args":{pattern:/(^options)[-'"|/\\<>*+=:()\w\s]*(?=;)/im,lookbehind:!0,inside:c},"cas-actions":g,comment:s,function:l,format:d,altformat:p,"numeric-constant":n,datetime:{pattern:RegExp(t+"(?:dt?|t)"),alias:"number"},string:r,step:i,keyword:k,"operator-keyword":{pattern:/\b(?:eq|ne|gt|lt|ge|le|in|not)\b/i,alias:"operator"},number:a,operator:/\*\*?|\|\|?|!!?|¦¦?|<[>=]?|>[<=]?|[-+\/=&]|[~¬^]=?/i,punctuation:o}}(Prism); \ No newline at end of file +!function(e){var t="(?:\"(?:\"\"|[^\"])*\"(?!\")|'(?:''|[^'])*'(?!'))",a=/\b(?:\d[\da-f]*x|\d+(?:\.\d+)?(?:e[+-]?\d+)?)\b/i,n={pattern:RegExp(t+"[bx]"),alias:"number"},i={pattern:/(^|\s+)(?:proc\s+\w+|quit|run|data(?!\=))\b/i,alias:"keyword",lookbehind:!0},s=[/\/\*[\s\S]*?\*\//,{pattern:/(^\s*|;\s*)\*[^;]*;/m,lookbehind:!0}],r={pattern:RegExp(t),greedy:!0},o=/[$%@.(){}\[\];,\\]/,l={pattern:/%?\w+(?=\()/,alias:"keyword"},c={function:l,"arg-value":{pattern:/(\s*=\s*)[A-Z\.]+/i,lookbehind:!0},operator:/=/,"macro-variable":{pattern:/&[^\.]*\./i,alias:"string"},arg:{pattern:/[A-Z]+/i,alias:"keyword"},number:a,"numeric-constant":n,punctuation:o,string:r},d={pattern:/\b(?:format|put)\b=?[\w'$.]+/im,inside:{keyword:/^(?:format|put)(?=\=)/i,equals:/=/,format:{pattern:/(?:\w|\$\d)+\.\d?/i,alias:"number"}}},p={pattern:/\b(?:format|put)\s+[\w']+(?:\s+[$.\w]+)+(?=;)/i,inside:{keyword:/^(?:format|put)/i,format:{pattern:/[\w$]+\.\d?/,alias:"number"}}},u={pattern:/((?:^|[\s])=?)(?:catname|checkpoint execute_always|dm|endsas|filename|footnote|%include|libname|%list|lock|missing|options|page|resetline|%run|sasfile|skip|sysecho|title\d?)\b/i,lookbehind:!0,alias:"keyword"},m={pattern:/(^|\s)(?:submit(?:\s+(?:load|parseonly|norun))?|endsubmit)\b/i,lookbehind:!0,alias:"keyword"},b="accessControl|cdm|aggregation|aStore|ruleMining|audio|autotune|bayesianNetClassifier|bioMedImage|boolRule|builtins|cardinality|sccasl|clustering|copula|countreg|dataDiscovery|dataPreprocess|dataSciencePilot|dataStep|decisionTree|deepLearn|deepNeural|varReduce|simSystem|ds2|deduplication|ecm|entityRes|espCluster|explainModel|factmac|fastKnn|fcmpact|fedSql|freqTab|gam|gleam|graphSemiSupLearn|gVarCluster|hiddenMarkovModel|hyperGroup|image|iml|ica|kernalPca|langModel|ldaTopic|sparseML|mlTools|mixed|modelPublishing|mbc|network|optNetwork|neuralNet|nonlinear|nmf|nonParametricBayes|optimization|panel|pls|percentile|pca|phreg|qkb|qlim|quantreg|recommend|tsReconcile|deepRnn|regression|reinforcementLearn|robustPca|sampling|sparkEmbeddedProcess|search(?:Analytics)?|sentimentAnalysis|sequence|configuration|session(?:Prop)?|severity|simple|smartData|sandwich|spatialreg|stabilityMonitoring|spc|loadStreams|svDataDescription|svm|table|conditionalRandomFields|text(?:Rule(?:Develop|Score)|Mining|Parse|Topic|Util|Filters|Frequency)|tsInfo|timeData|transpose|uniTimeSeries",g={pattern:RegExp("(^|\\s)(?:action\\s+)?(?:)\\.[a-z]+\\b[^;]+".replace(//g,function(){return b}),"i"),lookbehind:!0,inside:{keyword:RegExp("(?:)\\.[a-z]+\\b".replace(//g,function(){return b}),"i"),action:{pattern:/(?:action)/i,alias:"keyword"},comment:s,function:l,"arg-value":c["arg-value"],operator:c.operator,argument:c.arg,number:a,"numeric-constant":n,punctuation:o,string:r}},k={pattern:/((?:^|\s)=?)(?:after|analysis|and|array|barchart|barwidth|begingraph|by|call|cas|cbarline|cfill|class(?:lev)?|close|column|computed?|contains|continue|data(?=\=)|define|delete|describe|document|do\s+over|do|dol|drop|dul|end(?:source|comp)?|entryTitle|else|eval(?:uate)?|exec(?:ute)?|exit|fill(?:attrs)?|file(?:name)?|flist|fnc|function(?:list)?|goto|global|group(?:by)?|headline|headskip|histogram|if|infile|keep|keylabel|keyword|label|layout|leave|legendlabel|length|libname|loadactionset|merge|midpoints|name|noobs|nowd|_?null_|ods|options|or|otherwise|out(?:put)?|over(?:lay)?|plot|put|print|raise|ranexp|rannor|rbreak|retain|return|select|set|session|sessref|source|statgraph|sum|summarize|table|temp|terminate|then\s+do|then|title\d?|to|var|when|where|xaxisopts|yaxisopts|y2axisopts)\b/i,lookbehind:!0};e.languages.sas={datalines:{pattern:/^(\s*)(?:(?:data)?lines|cards);[\s\S]+?^\s*;/im,lookbehind:!0,alias:"string",inside:{keyword:{pattern:/^(?:(?:data)?lines|cards)/i},punctuation:/;/}},"proc-sql":{pattern:/(^proc\s+(?:fed)?sql(?:\s+[\w|=]+)?;)[\s\S]+?(?=^(?:proc\s+\w+|quit|run|data);|(?![\s\S]))/im,lookbehind:!0,inside:{sql:{pattern:RegExp("^[ \t]*(?:select|alter\\s+table|(?:create|describe|drop)\\s+(?:index|table(?:\\s+constraints)?|view)|create\\s+unique\\s+index|insert\\s+into|update)(?:|[^;\"'])+;".replace(//g,function(){return t}),"im"),alias:"language-sql",inside:e.languages.sql},"global-statements":u,"sql-statements":{pattern:/(^|\s)(?:disconnect\s+from|exec(?:ute)?|begin|commit|rollback|reset|validate)\b/i,lookbehind:!0,alias:"keyword"},number:a,"numeric-constant":n,punctuation:o,string:r}},"proc-groovy":{pattern:/(^proc\s+groovy(?:\s+[\w|=]+)?;)[\s\S]+?(?=^(?:proc\s+\w+|quit|run|data);|(?![\s\S]))/im,lookbehind:!0,inside:{comment:s,groovy:{pattern:RegExp("(^[ \t]*submit(?:\\s+(?:load|parseonly|norun))?)(?:|[^\"'])+?(?=endsubmit;)".replace(//g,function(){return t}),"im"),lookbehind:!0,alias:"language-groovy",inside:e.languages.groovy},keyword:k,"submit-statement":m,"global-statements":u,number:a,"numeric-constant":n,punctuation:o,string:r}},"proc-lua":{pattern:/(^proc\s+lua(?:\s+[\w|=]+)?;)[\s\S]+?(?=^(?:proc\s+\w+|quit|run|data);|(?![\s\S]))/im,lookbehind:!0,inside:{comment:s,lua:{pattern:RegExp("(^[ \t]*submit(?:\\s+(?:load|parseonly|norun))?)(?:|[^\"'])+?(?=endsubmit;)".replace(//g,function(){return t}),"im"),lookbehind:!0,alias:"language-lua",inside:e.languages.lua},keyword:k,"submit-statement":m,"global-statements":u,number:a,"numeric-constant":n,punctuation:o,string:r}},"proc-cas":{pattern:/(^proc\s+cas(?:\s+[\w|=]+)?;)[\s\S]+?(?=^(?:proc\s+\w+|quit|data);|(?![\s\S]))/im,lookbehind:!0,inside:{comment:s,"statement-var":{pattern:/((?:^|\s)=?)saveresult\s+[^;]+/im,lookbehind:!0,inside:{statement:{pattern:/^saveresult\s+\S+/i,inside:{keyword:/^(?:saveresult)/i}},rest:c}},"cas-actions":g,statement:{pattern:/((?:^|\s)=?)(?:default|(?:un)?set|on|output|upload)[^;]+/im,lookbehind:!0,inside:c},step:i,keyword:k,function:l,format:d,altformat:p,"global-statements":u,number:a,"numeric-constant":n,punctuation:o,string:r}},"proc-args":{pattern:RegExp("(^proc\\s+\\w+\\s+)(?!\\s)(?:[^;\"']|)+;".replace(//g,function(){return t}),"im"),lookbehind:!0,inside:c},"macro-string-functions":{pattern:/((?:^|\s|=))%(?:NRBQUOTE|NRQUOTE|NRSTR|BQUOTE|QUOTE|STR)\(.*?(?:[^%]\))/i,lookbehind:!0,inside:{function:{pattern:/%(?:NRBQUOTE|NRQUOTE|NRSTR|BQUOTE|QUOTE|STR)/i,alias:"keyword"},string:{pattern:/(\()[^)]+/,lookbehind:!0},punctuation:o}},"macro-keyword":{pattern:/((?:^|\s)=?)%(?:ABORT|BQUOTE|BY|CMS|COPY|DISPLAY|DO|ELSE|END|EVAL|GLOBAL|GO|GOTO|IF|INC|INCLUDE|INDEX|INPUT|KTRIM|LENGTH|LET|LIST|LOCAL|NRBQUOTE|NRQUOTE|NRSTR|PUT|QKTRIM|QSCAN|QSUBSTR|QSYSFUNC|QUOTE|QUPCASE|RETURN|RUN|SCAN|STR|SUBSTR|SUPERQ|SYMDEL|SYMGLOBL|SYMLOCAL|SYMEXIST|SYSCALL|SYSEVALF|SYSEXEC|SYSFUNC|SYSGET|SYSRPUT|THEN|TO|TSO|UNQUOTE|UNTIL|UPCASE|WHILE|WINDOW)\b/i,lookbehind:!0,alias:"keyword"},"macro-declaration":{pattern:/^%macro[^;]+(?=;)/im,inside:{keyword:/%macro/i}},"macro-end":{pattern:/^%mend[^;]+(?=;)/im,inside:{keyword:/%mend/i}},macro:{pattern:/%_\w+(?=\()/,alias:"keyword"},input:{pattern:/\binput\s+[-\w\s/*.$&]+;/i,inside:{input:{alias:"keyword",pattern:/^input/i},comment:s,number:a,"numeric-constant":n}},"options-args":{pattern:/(^options)[-'"|/\\<>*+=:()\w\s]*(?=;)/im,lookbehind:!0,inside:c},"cas-actions":g,comment:s,function:l,format:d,altformat:p,"numeric-constant":n,datetime:{pattern:RegExp(t+"(?:dt?|t)"),alias:"number"},string:r,step:i,keyword:k,"operator-keyword":{pattern:/\b(?:eq|ne|gt|lt|ge|le|in|not)\b/i,alias:"operator"},number:a,operator:/\*\*?|\|\|?|!!?|¦¦?|<[>=]?|>[<=]?|[-+\/=&]|[~¬^]=?/i,punctuation:o}}(Prism); \ No newline at end of file diff --git a/tests/languages/sas/macro_string_function_feature.test b/tests/languages/sas/macro_string_function_feature.test new file mode 100644 index 0000000000..20dcc3600a --- /dev/null +++ b/tests/languages/sas/macro_string_function_feature.test @@ -0,0 +1,88 @@ +%let a=%bquote(' "); +%let b=%nrbquote(' "); +%let c=%nrquote(%' %"); +%let d=%nrstr(%' %"); +%let e=%quote(%' %"); +%let f=%str(%' %"); + +---------------------------------------------------- + +[ + ["macro-keyword", "%let"], + " a", + ["operator", "="], + ["macro-string-functions", + [ + ["function", "%bquote"], + ["punctuation", "("], + ["string", "' \""], + ["punctuation", ")"] + ] + ], + ["punctuation", ";"], + ["macro-keyword", "%let"], + " b", + ["operator", "="], + ["macro-string-functions", + [ + ["function", "%nrbquote"], + ["punctuation", "("], + ["string", "' \""], + ["punctuation", ")"] + ] + ], + ["punctuation", ";"], + ["macro-keyword", "%let"], + " c", + ["operator", "="], + ["macro-string-functions", + [ + ["function", "%nrquote"], + ["punctuation", "("], + ["string", "%' %\""], + ["punctuation", ")"] + ] + ], + ["punctuation", ";"], + ["macro-keyword", "%let"], + " d", + ["operator", "="], + ["macro-string-functions", + [ + ["function", "%nrstr"], + ["punctuation", "("], + ["string", "%' %\""], + ["punctuation", ")"] + ] + ], + ["punctuation", ";"], + ["macro-keyword", "%let"], + " e", + ["operator", "="], + ["macro-string-functions", + [ + ["function", "%quote"], + ["punctuation", "("], + ["string", "%' %\""], + ["punctuation", ")"] + ] + ], + ["punctuation", ";"], + ["macro-keyword", "%let"], + " f", + ["operator", "="], + ["macro-string-functions", + [ + ["function", "%str"], + ["punctuation", "("], + ["string", "%' %\""], + ["punctuation", ")"] + ] + ], + ["punctuation", ";" + ] +] + +---------------------------------------------------- + +Checks for all macro string functions. diff --git a/tests/languages/sas/macrokeyword_feature.test b/tests/languages/sas/macrokeyword_feature.test index ba05f776d1..790a94933a 100644 --- a/tests/languages/sas/macrokeyword_feature.test +++ b/tests/languages/sas/macrokeyword_feature.test @@ -1,13 +1,13 @@ -%ABORT %BQUOTE %BY %CMS %COPY %DISPLAY %DO %ELSE %END %EVAL %GLOBAL %GO %GOTO %IF %INC %INCLUDE -%INDEX %INPUT %KTRIM %LENGTH %LET %LIST %LOCAL %NRBQUOTE %NRQUOTE %NRSTR %PUT %QKTRIM %QSCAN -%QSUBSTR %QSYSFUNC %QUOTE %QUPCASE %RETURN %RUN %SCAN %STR %SUBSTR %SUPERQ %SYMDEL %SYMGLOBL +%ABORT %BY %CMS %COPY %DISPLAY %DO %ELSE %END %EVAL %GLOBAL %GO %GOTO %IF %INC %INCLUDE +%INDEX %INPUT %KTRIM %LENGTH %LET %LIST %LOCAL %PUT %QKTRIM %QSCAN +%QSUBSTR %QSYSFUNC %QUPCASE %RETURN %RUN %SCAN %SUBSTR %SUPERQ %SYMDEL %SYMGLOBL %SYMLOCAL %SYMEXIST %SYSCALL %SYSEVALF %SYSEXEC %SYSFUNC %SYSGET %SYSRPUT %THEN %TO %TSO %UNQUOTE %UNTIL %UPCASE %WHILE %WINDOW ---------------------------------------------------- [ - ["macro-keyword", "%ABORT"], ["macro-keyword", "%BQUOTE"], ["macro-keyword", "%BY"], + ["macro-keyword", "%ABORT"], ["macro-keyword", "%BY"], ["macro-keyword", "%CMS"], ["macro-keyword", "%COPY"], ["macro-keyword", "%DISPLAY"], ["macro-keyword", "%DO"], ["macro-keyword", "%ELSE"], ["macro-keyword", "%END"], ["macro-keyword", "%EVAL"], ["macro-keyword", "%GLOBAL"], ["macro-keyword", "%GO"], @@ -15,13 +15,12 @@ ["macro-keyword", "%INCLUDE"], ["macro-keyword", "%INDEX"], ["macro-keyword", "%INPUT"], ["macro-keyword", "%KTRIM"], ["macro-keyword", "%LENGTH"], ["macro-keyword", "%LET"], ["macro-keyword", "%LIST"], - ["macro-keyword", "%LOCAL"], ["macro-keyword", "%NRBQUOTE"], - ["macro-keyword", "%NRQUOTE"], ["macro-keyword", "%NRSTR"], + ["macro-keyword", "%LOCAL"], ["macro-keyword", "%PUT"], ["macro-keyword", "%QKTRIM"], ["macro-keyword", "%QSCAN"], ["macro-keyword", "%QSUBSTR"], - ["macro-keyword", "%QSYSFUNC"], ["macro-keyword", "%QUOTE"], + ["macro-keyword", "%QSYSFUNC"], ["macro-keyword", "%QUPCASE"], ["macro-keyword", "%RETURN"], - ["macro-keyword", "%RUN"], ["macro-keyword", "%SCAN"], ["macro-keyword", "%STR"], + ["macro-keyword", "%RUN"], ["macro-keyword", "%SCAN"], ["macro-keyword", "%SUBSTR"], ["macro-keyword", "%SUPERQ"], ["macro-keyword", "%SYMDEL"], ["macro-keyword", "%SYMGLOBL"], ["macro-keyword", "%SYMLOCAL"], ["macro-keyword", "%SYMEXIST"],