SAS: Major improvements (#1981)

This makes various improvements to the SAS language definition such as adding support for embedded SQL, missing keyword and language elements, more granular tokenizing, and many more.
This commit is contained in:
cedporter 2019-08-08 15:16:31 -04:00 committed by Michael Schmidt
parent 508d57ac34
commit 076f615548
22 changed files with 847 additions and 50 deletions

File diff suppressed because one or more lines are too long

View File

@ -816,6 +816,7 @@
},
"sas": {
"title": "SAS",
"require": "sql",
"owner": "Golmote"
},
"sass": {

View File

@ -1,34 +1,184 @@
Prism.languages.sas = {
'datalines': {
pattern: /^\s*(?:(?:data)?lines|cards);[\s\S]+?(?:\r?\n|\r);/im,
alias: 'string',
inside: {
'keyword': {
pattern: /^(\s*)(?:(?:data)?lines|cards)/i,
lookbehind: true
},
'punctuation': /;/
}
},
'comment': [
(function (Prism) {
var stringPattern = /(["'])(?:\1\1|(?!\1)[\s\S])*\1(?!\1)/.source;
var number = /\b(?:\d[\da-f]*x|\d+(?:\.\d+)?(?:e[+-]?\d+)?)\b/i;
var numericConstant = {
pattern: RegExp(stringPattern + '[bx]'),
alias: 'number'
};
var step = {
pattern: /(^|\s+)(?:proc\s+\w+|quit|run|data(?!\=))\b/i,
alias: 'keyword',
lookbehind: true
};
var comment = [
{
pattern: /(^\s*|;\s*)\*.*;/m,
pattern: /(^\s*|;\s*)\*[^;]*;/m,
lookbehind: true
},
/\/\*[\s\S]+?\*\//
],
'datetime': {
// '1jan2013'd, '9:25:19pm't, '18jan2003:9:27:05am'dt
pattern: /'[^']+'(?:dt?|t)\b/i,
alias: 'number'
},
'string': {
pattern: /(["'])(?:\1\1|(?!\1)[\s\S])*\1/,
];
var string = {
pattern: RegExp(stringPattern),
greedy: true
},
'keyword': /\b(?:data|else|format|if|input|proc\s\w+|quit|run|then|libname|set|output|options)\b/i,
// Decimal (1.2e23), hexadecimal (0c1x)
'number': /\b(?:[\da-f]+x|\d+(?:\.\d+)?(?:e[+-]?\d+)?)/i,
'operator': /\*\*?|\|\|?|!!?|¦¦?|<[>=]?|>[<=]?|[-+\/=&]|[~¬^]=?|\b(?:eq|ne|gt|lt|ge|le|in|not)\b/i,
'punctuation': /[$%@.(){}\[\];,\\]/
};
};
var punctuation = /[$%@.(){}\[\];,\\]/;
var args = {
'arg-value': {
pattern: /(=)[A-Z]+/i,
lookbehind: true
},
'operator': /=/,
'arg': {
pattern: /[A-Z]+/i,
alias: 'keyword'
},
'number': number,
'numeric-constant': numericConstant,
'punctuation': punctuation,
'string': string
};
var globalStatements = {
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: true,
alias: 'keyword'
};
Prism.languages.sas = {
'datalines': {
pattern: /^(\s*)(?:(?:data)?lines|cards);[\s\S]+?^;/im,
lookbehind: true,
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: true,
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)(?:<str>|[^;"'])+;/.source.replace(/<str>/g, stringPattern), 'im'),
alias: 'language-sql',
inside: Prism.languages.sql
},
'global-statements': globalStatements,
'sql-statements': {
pattern: /(^|\s)(?:disconnect\s+from|exec(?:ute)?|begin|commit|rollback|reset|validate)\b/i,
lookbehind: true,
alias: 'keyword'
},
'number': number,
'numeric-constant': numericConstant,
'punctuation': punctuation,
'string': string
}
},
'proc-args': {
pattern: RegExp(/(^proc\s+\w+\s+)(?!\s)(?:[^;"']|<str>)+;/.source.replace(/<str>/g, stringPattern), 'im'),
lookbehind: true,
inside: args
},
/*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,
lookbehind: true,
alias: 'keyword'
},
'macro-declaration': {
pattern: /^%macro[^;]+(?=;)/im,
inside: {
'keyword': /%macro/i,
}
},
'macro-end': {
pattern: /^%mend[^;]+(?=;)/im,
inside: {
'keyword': /%mend/i,
}
},
/*%_zscore(headcir, _lhc, _mhc, _shc, headcz, headcpct, _Fheadcz); */
'macro': {
pattern: /%_\w+(?=\()/,
alias: 'keyword'
},
'input': {
pattern: /\binput\s+[-\w\s/*.$&]+;/i,
inside: {
'input': {
alias: 'keyword',
pattern: /^input/i,
},
'comment': comment,
'number': number,
'numeric-constant': numericConstant
}
},
'comment': comment,
'options-args': {
pattern: /(^options)[-'"|/\\<>*+=:()\w\s]*(?=;)/im,
lookbehind: true,
inside: args
},
'function': {
pattern: /%?\w+(?=\()/,
alias: 'keyword'
},
'format': {
pattern: /\b(?:format|put)\b=?[\w'$.]+/im,
inside: {
'keyword': /^(?:format|put)(?=\=)/i,
'equals': /=/,
'format': {
pattern: /(?:\w|\$\d)+\.\d?/i,
alias: 'number'
}
}
},
'altformat': {
pattern: /\b(?:format|put)\s+[\w']+(?:\s+[$.\w]+)+(?=;)/i,
inside: {
'keyword': /^(?:format|put)/i,
'format': {
pattern: /[\w$]+\.\d?/,
alias: 'number'
}
}
},
'numeric-constant': numericConstant,
'datetime': {
// '1jan2013'd, '9:25:19pm't, '18jan2003:9:27:05am'dt
pattern: RegExp(stringPattern + '(?:dt?|t)'),
alias: 'number'
},
'string': string,
'step': step,
'keyword': {
pattern: /((?:^|\s)=?)(?:action|after|analysis|and|array|barchart|barwidth|begingraph|by|cas|cbarline|cfill|close|column|computed?|contains|data(?=\=)|define|document|do\s+over|do|dol|drop|dul|end|entryTitle|else|endcomp|fill(?:attrs)?|filename|group(?:by)?|headline|headskip|histogram|if|infile|keep|label|layout|legendlabel|length|libname|merge|midpoints|name|noobs|nowd|ods|options|or|out(?:put)?|overlay|plot|ranexp|rannor|rbreak|retain|set|session|sessref|statgraph|sum|summarize|table|temp|then\sdo|then|title\d?|to|var|where|xaxisopts|yaxisopts|y2axisopts)\b/i,
lookbehind: true,
},
// In SAS Studio syntax highlighting, these operators are styled like keywords
'operator-keyword': {
pattern: /\b(?:eq|ne|gt|lt|ge|le|in|not)\b/i,
alias: 'operator'
},
// Decimal (1.2e23), hexadecimal (0c1x)
'number': number,
'operator': /\*\*?|\|\|?|!!?|¦¦?|<[>=]?|>[<=]?|[-+\/=&]|[~¬^]=?/i,
'punctuation': punctuation
};
}(Prism));

View File

@ -1 +1 @@
Prism.languages.sas={datalines:{pattern:/^\s*(?:(?:data)?lines|cards);[\s\S]+?(?:\r?\n|\r);/im,alias:"string",inside:{keyword:{pattern:/^(\s*)(?:(?:data)?lines|cards)/i,lookbehind:!0},punctuation:/;/}},comment:[{pattern:/(^\s*|;\s*)\*.*;/m,lookbehind:!0},/\/\*[\s\S]+?\*\//],datetime:{pattern:/'[^']+'(?:dt?|t)\b/i,alias:"number"},string:{pattern:/(["'])(?:\1\1|(?!\1)[\s\S])*\1/,greedy:!0},keyword:/\b(?:data|else|format|if|input|proc\s\w+|quit|run|then|libname|set|output|options)\b/i,number:/\b(?:[\da-f]+x|\d+(?:\.\d+)?(?:e[+-]?\d+)?)/i,operator:/\*\*?|\|\|?|!!?|¦¦?|<[>=]?|>[<=]?|[-+\/=&]|[~¬^]=?|\b(?:eq|ne|gt|lt|ge|le|in|not)\b/i,punctuation:/[$%@.(){}\[\];,\\]/};
!function(e){var t="([\"'])(?:\\1\\1|(?!\\1)[\\s\\S])*\\1(?!\\1)",a=/\b(?:\d[\da-f]*x|\d+(?:\.\d+)?(?:e[+-]?\d+)?)\b/i,n={pattern:RegExp(t+"[bx]"),alias:"number"},i=[{pattern:/(^\s*|;\s*)\*[^;]*;/m,lookbehind:!0},/\/\*[\s\S]+?\*\//],r={pattern:RegExp(t),greedy:!0},s=/[$%@.(){}\[\];,\\]/,o={"arg-value":{pattern:/(=)[A-Z]+/i,lookbehind:!0},operator:/=/,arg:{pattern:/[A-Z]+/i,alias:"keyword"},number:a,"numeric-constant":n,punctuation:s,string:r};e.languages.sas={datalines:{pattern:/^(\s*)(?:(?:data)?lines|cards);[\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)(?:<str>|[^;\"'])+;".replace(/<str>/g,t),"im"),alias:"language-sql",inside:e.languages.sql},"global-statements":{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"},"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:s,string:r}},"proc-args":{pattern:RegExp("(^proc\\s+\\w+\\s+)(?!\\s)(?:[^;\"']|<str>)+;".replace(/<str>/g,t),"im"),lookbehind:!0,inside: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:i,number:a,"numeric-constant":n}},comment:i,"options-args":{pattern:/(^options)[-'"|/\\<>*+=:()\w\s]*(?=;)/im,lookbehind:!0,inside:o},function:{pattern:/%?\w+(?=\()/,alias:"keyword"},format:{pattern:/\b(?:format|put)\b=?[\w'$.]+/im,inside:{keyword:/^(?:format|put)(?=\=)/i,equals:/=/,format:{pattern:/(?:\w|\$\d)+\.\d?/i,alias:"number"}}},altformat:{pattern:/\b(?:format|put)\s+[\w']+(?:\s+[$.\w]+)+(?=;)/i,inside:{keyword:/^(?:format|put)/i,format:{pattern:/[\w$]+\.\d?/,alias:"number"}}},"numeric-constant":n,datetime:{pattern:RegExp(t+"(?:dt?|t)"),alias:"number"},string:r,step:{pattern:/(^|\s+)(?:proc\s+\w+|quit|run|data(?!\=))\b/i,alias:"keyword",lookbehind:!0},keyword:{pattern:/((?:^|\s)=?)(?:action|after|analysis|and|array|barchart|barwidth|begingraph|by|cas|cbarline|cfill|close|column|computed?|contains|data(?=\=)|define|document|do\s+over|do|dol|drop|dul|end|entryTitle|else|endcomp|fill(?:attrs)?|filename|group(?:by)?|headline|headskip|histogram|if|infile|keep|label|layout|legendlabel|length|libname|merge|midpoints|name|noobs|nowd|ods|options|or|out(?:put)?|overlay|plot|ranexp|rannor|rbreak|retain|set|session|sessref|statgraph|sum|summarize|table|temp|then\sdo|then|title\d?|to|var|where|xaxisopts|yaxisopts|y2axisopts)\b/i,lookbehind:!0},"operator-keyword":{pattern:/\b(?:eq|ne|gt|lt|ge|le|in|not)\b/i,alias:"operator"},number:a,operator:/\*\*?|\|\|?|!!?|¦¦?|<[>=]?|>[<=]?|[-+\/=&]|[~¬^]=?/i,punctuation:s}}(Prism);

View File

@ -6,7 +6,7 @@ multi-line comment */
<h2>Numbers, dates and times</h2>
<pre><code>42; 4.5; 4.5e-10; -3; -3.5e2; -4.2e-23;
0afx; 0123x; abcdefx;
0afx; 0123x;
'1jan2013'd; '01jan09'd;
'9:25't; '9:25:19pm't;
'01may12:9:30:00'dt; '18jan2003:9:27:05am'dt;
@ -31,7 +31,8 @@ state in ('NY','NJ','PA');
not a;</code></pre>
<h2>More examples</h2>
<pre><code>/* Some examples adapted from the documentation (http://support.sas.com/documentation/cdl/en/basess/64003/PDF/default/basess.pdf) */
<pre><code>/* Some examples adapted from the documentation
http://support.sas.com/documentation/cdl/en/basess/64003/PDF/default/basess.pdf */
data city; * another inline comment;

View File

@ -91,6 +91,7 @@
],
"reason": "clike",
"ruby": "clike",
"sas": "sql",
"sass": "css",
"scss": "css",
"scala": "java",

View File

@ -1 +1 @@
!function(){if("undefined"!=typeof self&&self.Prism&&self.document&&document.createElement){var r={javascript:"clike",actionscript:"javascript",arduino:"cpp",aspnet:["markup","csharp"],bison:"c",c:"clike",csharp:"clike",cpp:"c",coffeescript:"javascript",crystal:"ruby","css-extras":"css",d:"clike",dart:"clike",django:"markup-templating",ejs:["javascript","markup-templating"],erb:["ruby","markup-templating"],fsharp:"clike",flow:"javascript",glsl:"clike",gml:"clike",go:"clike",groovy:"clike",haml:"ruby",handlebars:"markup-templating",haxe:"clike",java:"clike",javadoc:["markup","java","javadoclike"],jolie:"clike",jsdoc:["javascript","javadoclike"],"js-extras":"javascript","js-templates":"javascript",jsonp:"json",json5:"json",kotlin:"clike",less:"css",lilypond:"scheme",markdown:"markup","markup-templating":"markup",n4js:"javascript",nginx:"clike",objectivec:"c",opencl:"cpp",parser:"markup",php:["clike","markup-templating"],phpdoc:["php","javadoclike"],"php-extras":"php",plsql:"sql",processing:"clike",protobuf:"clike",pug:["markup","javascript"],qore:"clike",jsx:["markup","javascript"],tsx:["jsx","typescript"],reason:"clike",ruby:"clike",sass:"css",scss:"css",scala:"java","shell-session":"bash",smarty:"markup-templating",soy:"markup-templating",swift:"clike",tap:"yaml",textile:"markup",tt2:["clike","markup-templating"],twig:"markup",typescript:"javascript","t4-cs":["t4-templating","csharp"],"t4-vb":["t4-templating","visual-basic"],vala:"clike",vbnet:"basic",velocity:"markup",wiki:"markup",xeora:"markup",xquery:"markup"},n={html:"markup",xml:"markup",svg:"markup",mathml:"markup",js:"javascript",adoc:"asciidoc",shell:"bash",rbnf:"bnf",cs:"csharp",dotnet:"csharp",coffee:"coffeescript",jinja2:"django","dns-zone":"dns-zone-file",dockerfile:"docker",gamemakerlanguage:"gml",hs:"haskell",tex:"latex",context:"latex",ly:"lilypond",emacs:"lisp",elisp:"lisp","emacs-lisp":"lisp",md:"markdown",n4jsd:"n4js",objectpascal:"pascal",px:"pcaxis",py:"python",rb:"ruby",trig:"turtle",ts:"typescript",t4:"t4-cs",vb:"visual-basic",xeoracube:"xeora",yml:"yaml"},l={},e=document.getElementsByTagName("script"),a=e[e.length-1],t="components/",s=/\bplugins\/autoloader\/prism-autoloader\.(?:min\.)js$/i,i=/[\w-]+\.(?:min\.)js$/i;if(a.hasAttribute("data-autoloader-path"))t=a.getAttribute("data-autoloader-path").trim().replace(/\/?$/,"/");else{var c=a.src;s.test(c)?t=c.replace(s,"components/"):i.test(c)&&(t=c.replace(i,"components/"))}var p=Prism.plugins.autoloader={languages_path:t,use_minified:!0,loadLanguages:o};Prism.hooks.add("complete",function(e){e.element&&e.language&&!e.grammar&&"none"!==e.language&&function(e,a){e in n&&(e=n[e]);var t=a.getAttribute("data-dependencies"),s=a.parentElement;!t&&s&&"pre"===s.tagName.toLowerCase()&&(t=s.getAttribute("data-dependencies")),o(t=t?t.split(/\s*,\s*/g):[],function(){m(e,function(){Prism.highlightElement(a)})})}(e.language,e.element)})}function o(e,a,t){"string"==typeof e&&(e=[e]);var s=e.length,i=0,c=!1;function r(){c||++i===s&&a&&a(e)}0!==s?e.forEach(function(e){m(e,r,function(){c||(c=!0,t&&t(e))})}):a&&setTimeout(a,0)}function m(a,t,s){var i=0<=a.indexOf("!");a=a.replace("!",""),a=n[a]||a;var e=function(){var e=l[a];if(e||(e=l[a]={callbacks:[]}),e.callbacks.push({success:t,error:s}),!i&&Prism.languages[a])u(a,"success");else if(!i&&e.error)u(a,"error");else if(i||!e.loading){e.loading=!0,function(e,a,t){var s=document.createElement("script");s.src=e,s.async=!0,s.onload=function(){document.body.removeChild(s),a&&a()},s.onerror=function(){document.body.removeChild(s),t&&t()},document.body.appendChild(s)}(function(e){return p.languages_path+"prism-"+e+(p.use_minified?".min":"")+".js"}(a),function(){e.loading=!1,u(a,"success")},function(){e.loading=!1,e.error=!0,u(a,"error")})}},c=r[a];c&&c.length?o(c,e,s):e()}function u(e,a){if(l[e]){for(var t=l[e].callbacks,s=0,i=t.length;s<i;s++){var c=t[s][a];c&&setTimeout(c,0)}t.length=0}}}();
!function(){if("undefined"!=typeof self&&self.Prism&&self.document&&document.createElement){var r={javascript:"clike",actionscript:"javascript",arduino:"cpp",aspnet:["markup","csharp"],bison:"c",c:"clike",csharp:"clike",cpp:"c",coffeescript:"javascript",crystal:"ruby","css-extras":"css",d:"clike",dart:"clike",django:"markup-templating",ejs:["javascript","markup-templating"],erb:["ruby","markup-templating"],fsharp:"clike",flow:"javascript",glsl:"clike",gml:"clike",go:"clike",groovy:"clike",haml:"ruby",handlebars:"markup-templating",haxe:"clike",java:"clike",javadoc:["markup","java","javadoclike"],jolie:"clike",jsdoc:["javascript","javadoclike"],"js-extras":"javascript","js-templates":"javascript",jsonp:"json",json5:"json",kotlin:"clike",less:"css",lilypond:"scheme",markdown:"markup","markup-templating":"markup",n4js:"javascript",nginx:"clike",objectivec:"c",opencl:"cpp",parser:"markup",php:["clike","markup-templating"],phpdoc:["php","javadoclike"],"php-extras":"php",plsql:"sql",processing:"clike",protobuf:"clike",pug:["markup","javascript"],qore:"clike",jsx:["markup","javascript"],tsx:["jsx","typescript"],reason:"clike",ruby:"clike",sas:"sql",sass:"css",scss:"css",scala:"java","shell-session":"bash",smarty:"markup-templating",soy:"markup-templating",swift:"clike",tap:"yaml",textile:"markup",tt2:["clike","markup-templating"],twig:"markup",typescript:"javascript","t4-cs":["t4-templating","csharp"],"t4-vb":["t4-templating","visual-basic"],vala:"clike",vbnet:"basic",velocity:"markup",wiki:"markup",xeora:"markup",xquery:"markup"},l={html:"markup",xml:"markup",svg:"markup",mathml:"markup",js:"javascript",adoc:"asciidoc",shell:"bash",rbnf:"bnf",cs:"csharp",dotnet:"csharp",coffee:"coffeescript",jinja2:"django","dns-zone":"dns-zone-file",dockerfile:"docker",gamemakerlanguage:"gml",hs:"haskell",tex:"latex",context:"latex",ly:"lilypond",emacs:"lisp",elisp:"lisp","emacs-lisp":"lisp",md:"markdown",n4jsd:"n4js",objectpascal:"pascal",px:"pcaxis",py:"python",rb:"ruby",trig:"turtle",ts:"typescript",t4:"t4-cs",vb:"visual-basic",xeoracube:"xeora",yml:"yaml"},n={},e=document.getElementsByTagName("script"),a=e[e.length-1],t="components/",s=/\bplugins\/autoloader\/prism-autoloader\.(?:min\.)js$/i,i=/[\w-]+\.(?:min\.)js$/i;if(a.hasAttribute("data-autoloader-path"))t=a.getAttribute("data-autoloader-path").trim().replace(/\/?$/,"/");else{var c=a.src;s.test(c)?t=c.replace(s,"components/"):i.test(c)&&(t=c.replace(i,"components/"))}var p=Prism.plugins.autoloader={languages_path:t,use_minified:!0,loadLanguages:o};Prism.hooks.add("complete",function(e){e.element&&e.language&&!e.grammar&&"none"!==e.language&&function(e,a){e in l&&(e=l[e]);var t=a.getAttribute("data-dependencies"),s=a.parentElement;!t&&s&&"pre"===s.tagName.toLowerCase()&&(t=s.getAttribute("data-dependencies")),o(t=t?t.split(/\s*,\s*/g):[],function(){m(e,function(){Prism.highlightElement(a)})})}(e.language,e.element)})}function o(e,a,t){"string"==typeof e&&(e=[e]);var s=e.length,i=0,c=!1;function r(){c||++i===s&&a&&a(e)}0!==s?e.forEach(function(e){m(e,r,function(){c||(c=!0,t&&t(e))})}):a&&setTimeout(a,0)}function m(a,t,s){var i=0<=a.indexOf("!");a=a.replace("!",""),a=l[a]||a;var e=function(){var e=n[a];if(e||(e=n[a]={callbacks:[]}),e.callbacks.push({success:t,error:s}),!i&&Prism.languages[a])u(a,"success");else if(!i&&e.error)u(a,"error");else if(i||!e.loading){e.loading=!0,function(e,a,t){var s=document.createElement("script");s.src=e,s.async=!0,s.onload=function(){document.body.removeChild(s),a&&a()},s.onerror=function(){document.body.removeChild(s),t&&t()},document.body.appendChild(s)}(function(e){return p.languages_path+"prism-"+e+(p.use_minified?".min":"")+".js"}(a),function(){e.loading=!1,u(a,"success")},function(){e.loading=!1,e.error=!0,u(a,"error")})}},c=r[a];c&&c.length?o(c,e,s):e()}function u(e,a){if(n[e]){for(var t=n[e].callbacks,s=0,i=t.length;s<i;s++){var c=t[s][a];c&&setTimeout(c,0)}t.length=0}}}();

View File

@ -35,4 +35,4 @@ baz
----------------------------------------------------
Checks for datalines.
Checks for datalines.

View File

@ -2,14 +2,23 @@
'9:25:19pm't
'18jan2003:9:27:05am'dt
* don't match the following just because of "'t";
'foo'¦¦'test';
----------------------------------------------------
[
["datetime", "'1jan2013'd"],
["datetime", "'9:25:19pm't"],
["datetime", "'18jan2003:9:27:05am'dt"]
["datetime", "'18jan2003:9:27:05am'dt"],
["comment", "* don't match the following just because of \"'t\";"],
["string", "'foo'"],
["operator", "¦¦"],
["string", "'test'"],
["punctuation", ";"]
]
----------------------------------------------------
Checks for date, times and datetimes.
Checks for date, times and datetimes.

View File

@ -0,0 +1,36 @@
put x $hex16.;
format salary uscurrency.;
format=dollar12.;
----------------------------------------------------
[
["altformat",
[
["keyword", "put"],
" x ",
["format", "$hex16."]
]
],
["punctuation", ";"],
["altformat",
[
["keyword","format"],
" salary ",
["format", "uscurrency."]
]
],
["punctuation", ";"],
["format",
[
["keyword", "format"],
["equals", "="],
["format", "dollar12."]
]
],
["punctuation", ";"]
]
----------------------------------------------------
Checks that options captures "options" and correctly tags following text.

View File

@ -0,0 +1,21 @@
function()
x=addrlong(item);
----------------------------------------------------
[
["function", "function"],
["punctuation", "("],
["punctuation", ")"],
"\r\nx",
["operator", "="],
["function", "addrlong"],
["punctuation", "("],
"item",
["punctuation", ")"],
["punctuation", ";"]
]
----------------------------------------------------
Checks that options captures "options" and correctly tags following text.

View File

@ -0,0 +1,42 @@
input name $ score1 score2 score3 team $;
input name $ & score;
input outlook $ 1-8 temperature humidity windy $ 16 - 21 /* golf $22 - 32 */;
----------------------------------------------------
[
[
"input",
[
["input", "input"],
" name $ score1 score2 score3 team $;"
]
],
[
"input",
[
["input", "input"],
" name $ & score;"
]
],
["input",
[
["input", "input"],
" outlook $ ",
["number", "1"],
"-",
["number", "8"],
" temperature humidity windy $ ",
["number", "16"],
" - ",
["number", "21"],
["comment", "/* golf $22 - 32 */"],
";"
]
]
]
----------------------------------------------------
Checks that input captures "input" and text that follows up to and including
the semicolon.

View File

@ -1,13 +1,40 @@
data else format if
input proc run then
libname set output options
action after analysis and array barchart barwidth begingraph by
cas cbarline cfill close column compute computed contains data= define
document do do over dol drop dul end entryTitle else endcomp fill fillattrs
filename group groupby headline headskip histogram if infile keep label layout
legendlabel length libname merge midpoints name noobs nowd ods or out output
overlay plot ranexp rannor rbreak retain set session sessref statgraph
sum summarize table temp then then do title to var where xaxisopts yaxisopts
y2axisopts
----------------------------------------------------
[
["keyword", "data"], ["keyword", "else"], ["keyword", "format"], ["keyword", "if"],
["keyword", "input"], ["keyword", "proc run"], ["keyword", "then"], ["keyword", "libname"],
["keyword", "set"], ["keyword", "output"], ["keyword", "options"]
["keyword", "action"], ["keyword", "after"], ["keyword", "analysis"],
["keyword", "and"], ["keyword", "array"], ["keyword", "barchart"],
["keyword", "barwidth"], ["keyword", "begingraph"], ["keyword", "by"],
["keyword", "cas"], ["keyword", "cbarline"], ["keyword", "cfill"],
["keyword", "close"], ["keyword", "column"], ["keyword", "compute"],
["keyword", "computed"], ["keyword", "contains"], ["keyword", "data"],
["operator", "="], ["keyword", "define"], ["keyword", "document"], ["keyword", "do"],
["keyword", "do over"], ["keyword", "dol"], ["keyword", "drop"], ["keyword", "dul"],
["keyword", "end"], ["keyword", "entryTitle"], ["keyword", "else"],
["keyword", "endcomp"], ["keyword", "fill"], ["keyword", "fillattrs"],
["keyword", "filename"], ["keyword", "group"], ["keyword", "groupby"],
["keyword", "headline"], ["keyword", "headskip"], ["keyword", "histogram"],
["keyword", "if"], ["keyword", "infile"], ["keyword", "keep"], ["keyword", "label"],
["keyword", "layout"], ["keyword", "legendlabel"], ["keyword", "length"],
["keyword", "libname"], ["keyword", "merge"], ["keyword", "midpoints"],
["keyword", "name"], ["keyword", "noobs"], ["keyword", "nowd"], ["keyword", "ods"],
["keyword", "or"], ["keyword", "out"], ["keyword", "output"], ["keyword", "overlay"],
["keyword", "plot"],
["keyword", "ranexp"], ["keyword", "rannor"], ["keyword", "rbreak"], ["keyword", "retain"],
["keyword", "set"], ["keyword", "session"], ["keyword", "sessref"], ["keyword", "statgraph"],
["keyword", "sum"], ["keyword", "summarize"], ["keyword", "table"],
["keyword", "temp"], ["keyword", "then"], ["keyword", "then do"],
["keyword", "title"], ["keyword", "to"], ["keyword", "var"],
["keyword", "where"], ["keyword", "xaxisopts"], ["keyword", "yaxisopts"],
["keyword", "y2axisopts"]
]
----------------------------------------------------

View File

@ -0,0 +1,23 @@
%_zscore(length);
%_test(string, 0.3);
----------------------------------------------------
[
["macro", "%_zscore"],
["punctuation", "("],
"length",
["punctuation", ")"],
["punctuation", ";"],
["macro", "%_test"],
["punctuation", "("],
"string",
["punctuation", ","],
["number", "0.3"],
["punctuation", ")"],
["punctuation", ";"]
]
----------------------------------------------------
Checks that options captures "options" and correctly tags following text.

View File

@ -0,0 +1,131 @@
%macro prnt(var,sum);
proc print data=srhigh;
var &var;
sum &sum;
run;
%mend prnt;
%macro printz/parmbuff;
%let num=1;
%let dsname=%scan(&syspbuff,&num);
%do %while(&dsname ne);
proc print data=&dsname;
run;
%let num=%eval(&num+1);
%let dsname=%scan(&syspbuff,&num);
%end;
%mend printz;
----------------------------------------------------
[
[
"macro-declaration",
[
["keyword", "%macro"],
" prnt(var,sum)"
]
],
["punctuation", ";"],
["step", "proc print"],
["keyword", "data"],
["operator", "="],
"srhigh",
["punctuation", ";"],
["keyword", "var"],
["operator", "&"],
"var",
["punctuation", ";"],
["keyword", "sum"],
["operator", "&"],
"sum",
["punctuation", ";"],
["step", "run"],
["punctuation", ";"],
[
"macro-end",
[
["keyword", "%mend"],
" prnt"
]
],
["punctuation", ";"],
[
"macro-declaration",
[
["keyword", "%macro"],
" printz/parmbuff"
]
],
["punctuation", ";"],
["macro-keyword", "%let"],
" num",
["operator", "="],
["number", "1"],
["punctuation", ";"],
["macro-keyword", "%let"],
" dsname",
["operator", "="],
["function", "%scan"],
["punctuation", "("],
["operator", "&"],
"syspbuff",
["punctuation", ","],
["operator", "&"],
"num",
["punctuation", ")"],
["punctuation", ";"],
["macro-keyword", "%do"],
["macro-keyword", "%while"],
["punctuation", "("],
["operator", "&"],
"dsname ",
["operator-keyword", "ne"],
["punctuation", ")"],
["punctuation", ";"],
["step", "proc print"],
["keyword", "data"],
["operator", "="],
["operator", "&"],
"dsname",
["punctuation", ";"],
["step", "run"],
["punctuation", ";"],
["macro-keyword", "%let"],
" num",
["operator", "="],
["function", "%eval"],
["punctuation", "("],
["operator", "&"],
"num",
["operator", "+"],
["number", "1"],
["punctuation", ")"],
["punctuation", ";"],
["macro-keyword", "%let"],
" dsname",
["operator", "="],
["function", "%scan"],
["punctuation", "("],
["operator", "&"],
"syspbuff",
["punctuation", ","],
["operator", "&"],
"num",
["punctuation", ")"],
["punctuation", ";"],
["macro-keyword", "%end"],
["punctuation", ";"],
[
"macro-end",
[
["keyword", "%mend"],
" printz"
]
],
["punctuation", ";"]
]
----------------------------------------------------
Checks that options captures "options" and correctly tags following text.

View File

@ -0,0 +1,39 @@
%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
----------------------------------------------------
[
["macro-keyword", "%ABORT"], ["macro-keyword", "%BQUOTE"], ["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"],
["macro-keyword", "%GOTO"], ["macro-keyword", "%IF"], ["macro-keyword", "%INC"],
["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", "%PUT"], ["macro-keyword", "%QKTRIM"],
["macro-keyword", "%QSCAN"], ["macro-keyword", "%QSUBSTR"],
["macro-keyword", "%QSYSFUNC"], ["macro-keyword", "%QUOTE"],
["macro-keyword", "%QUPCASE"], ["macro-keyword", "%RETURN"],
["macro-keyword", "%RUN"], ["macro-keyword", "%SCAN"], ["macro-keyword", "%STR"],
["macro-keyword", "%SUBSTR"], ["macro-keyword", "%SUPERQ"],
["macro-keyword", "%SYMDEL"], ["macro-keyword", "%SYMGLOBL"],
["macro-keyword", "%SYMLOCAL"], ["macro-keyword", "%SYMEXIST"],
["macro-keyword", "%SYSCALL"], ["macro-keyword", "%SYSEVALF"],
["macro-keyword", "%SYSEXEC"], ["macro-keyword", "%SYSFUNC"],
["macro-keyword", "%SYSGET"], ["macro-keyword", "%SYSRPUT"],
["macro-keyword", "%THEN"], ["macro-keyword", "%TO"], ["macro-keyword", "%TSO"],
["macro-keyword", "%UNQUOTE"], ["macro-keyword", "%UNTIL"],
["macro-keyword", "%UPCASE"], ["macro-keyword", "%WHILE"],
["macro-keyword", "%WINDOW"]
]
----------------------------------------------------
Checks for all keywords.

View File

@ -4,6 +4,8 @@
0.4e-8
1.4E+2
BadFacex
0c1x
0b0ax
----------------------------------------------------
@ -13,9 +15,11 @@ BadFacex
["number", "3.2e10"],
["number", "0.4e-8"],
["number", "1.4E+2"],
["number", "BadFacex"]
"\r\nBadFacex\r\n",
["number", "0c1x"],
["number", "0b0ax"]
]
----------------------------------------------------
Checks for decimal and hexadecimal numbers.
Checks for decimal and hexadecimal numbers.

View File

@ -27,11 +27,10 @@ ge le in not
["operator", "^"], ["operator", "^="],
["operator", "="], ["operator", "/"], ["operator", "+"],
["operator", "-"], ["operator", "&"],
["operator", "eq"], ["operator", "ne"], ["operator", "gt"], ["operator", "lt"],
["operator", "ge"], ["operator", "le"], ["operator", "in"], ["operator", "not"]
["operator-keyword", "eq"], ["operator-keyword", "ne"], ["operator-keyword", "gt"], ["operator-keyword", "lt"],
["operator-keyword", "ge"], ["operator-keyword", "le"], ["operator-keyword", "in"], ["operator-keyword", "not"]
]
----------------------------------------------------
Checks for operators.
Checks for operators.

View File

@ -0,0 +1,50 @@
options nodate linesize=72;
options validmemname=extend validvarname=any;
options insert=(fmtsearch="c:/myformats");
----------------------------------------------------
[
["keyword", "options"],
[
"options-args",
[
["arg","nodate"],
["arg", "linesize"],
["operator", "="],
["number", "72"]
]
],
["punctuation", ";"],
["keyword", "options"],
[
"options-args",
[
["arg", "validmemname"],
["operator", "="],
["arg-value", "extend"],
["arg", "validvarname"],
["operator", "="],
["arg-value", "any"]
]
],
["punctuation", ";"],
["keyword", "options"],
[
"options-args",
[
["arg", "insert"],
["operator", "="],
["punctuation", "("],
["arg", "fmtsearch"],
["operator", "="],
["string", "\"c:/myformats\""],
["punctuation", ")"]
]
],
["punctuation", ";"]
]
----------------------------------------------------
Checks that options captures "options" and correctly tags following text.

View File

@ -0,0 +1,233 @@
proc sql;
select *
from proclib.paylist;
proc print;
proc sql outobs=10;
title 'Proclib.Payroll';
select * from proclib.payroll;
title;
quit;
proc sql;
select BookingDate,
ReleaseDate,
ReleaseCode
from SASclass.Bookings;
quit;
proc sql;
select BookingDate,
ReleaseDate,
ReleaseCode
from SASclass.Bookings;
quit;
libname proclib 'SAS-library';
proc sql;
create view proclib.jobs(pw-red) as
select Jobcode,
count(jobcode) as number label='Number',
avg(int(today()-birth/365.25)) as avgage
format=2. label='Average Salary'
from Payroll
group by Jobcode
having avage ge 30;
title1 'Current Summary Information for Each Job category';
title2 'Average Age Greater Than or Equal to 30';
select * form proclib.jobs(pw=red);
title
----------------------------------------------------
[
["step", "proc sql"],
["punctuation", ";"],
["proc-sql",
[
["sql",
[
["keyword", "select"],
["operator", "*"],
["keyword", "from"],
" proclib",
["punctuation", "."],
"paylist",
["punctuation", ";"]
]
]
]
],
["step", "proc print"],
["punctuation", ";"],
["step", "proc sql"],
["proc-args",
[
["arg", "outobs"],
["operator", "="],
["number", "10"],
["punctuation", ";"]
]
],
["proc-sql",
[
["global-statements", "title"],
["string", "'Proclib.Payroll'"],
["punctuation", ";"],
["sql",
[
["keyword", "select"],
["operator", "*"],
["keyword", "from"],
" proclib",
["punctuation", "."],
"payroll",
["punctuation", ";"]
]
],
["global-statements", "title"],
["punctuation", ";"]
]
],
["step", "quit"],
["punctuation", ";"],
["step", "proc sql"],
["punctuation", ";"],
["proc-sql",
[
["sql",
[
["keyword", "select"],
" BookingDate",
["punctuation", ","],
"\r\n\tReleaseDate",
["punctuation", ","],
"\r\n\tReleaseCode\r\n\t",
["keyword", "from"],
" SASclass",
["punctuation", "."],
"Bookings",
["punctuation", ";"]
]
]
]
],
["step", "quit"],
["punctuation", ";"],
["step", "proc sql"],
["punctuation", ";"],
["proc-sql",
[
["sql",
[
["keyword", "select"],
" BookingDate",
["punctuation", ","],
"\r\n\tReleaseDate",
["punctuation", ","],
"\r\n\tReleaseCode\r\n\t",
["keyword", "from"],
" SASclass",
["punctuation", "."],
"Bookings",
["punctuation", ";"]
]
]
]
],
["step", "quit"],
["punctuation", ";"],
["keyword", "libname"],
" proclib ",
["string", "'SAS-library'"],
["punctuation", ";"],
["step", "proc sql"],
["punctuation", ";"],
["proc-sql",
[
["sql",
[
["keyword", "create"],
["keyword", "view"],
" proclib",
["punctuation", "."],
"jobs",
["punctuation", "("],
"pw",
["operator", "-"],
"red",
["punctuation", ")"],
["keyword", "as"],
["keyword", "select"],
" Jobcode",
["punctuation", ","],
["function", "count"],
["punctuation", "("],
"jobcode",
["punctuation", ")"],
["keyword", "as"],
" number label",
["operator", "="],
["string", "'Number'"],
["punctuation", ","],
["function", "avg"],
["punctuation", "("],
["keyword", "int"],
["punctuation", "("],
"today",
["punctuation", "("],
["punctuation", ")"],
["operator", "-"],
"birth",
["operator", "/"],
["number", "365.25"],
["punctuation", ")"],
["punctuation", ")"],
["keyword", "as"],
" avgage\r\n\t\t\tformat",
["operator", "="],
["number", "2."],
" label",
["operator", "="],
["string", "'Average Salary'"],
["keyword", "from"],
" Payroll\r\n\t",
["keyword", "group"],
["keyword", "by"],
" Jobcode\r\n\t",
["keyword", "having"],
" avage ge ",
["number", "30"],
["punctuation", ";"]
]
],
["global-statements", "title1"],
["string", "'Current Summary Information for Each Job category'"],
["punctuation", ";"],
["global-statements", "title2"],
["string", "'Average Age Greater Than or Equal to 30'"],
["punctuation", ";"],
["sql",
[
["keyword", "select"],
["operator", "*"],
" form proclib",
["punctuation", "."],
"jobs",
["punctuation", "("],
"pw",
["operator", "="],
"red",
["punctuation", ")"],
["punctuation", ";"]
]
],
["global-statements", "title"]
]
]
]
----------------------------------------------------
Checks that SQL captures SAS language elements and leverages
SQL language support for nested SQL.

View File

@ -0,0 +1,30 @@
data carsurvey;
proc format;
proc sort data=allacty;
run;
quit;
----------------------------------------------------
[
["step", "data"],
" carsurvey",
["punctuation", ";"],
["step", "proc format"],
["punctuation", ";"],
["step", "proc sort"],
["proc-args",[
["arg", "data"],
["operator", "="],
["arg-value", "allacty"],
["punctuation", ";"]
]],
["step", "run"],
["punctuation", ";"],
["step", "quit"],
["punctuation", ";"]
]
----------------------------------------------------
Checks that options captures "options" and correctly tags following text.

View File

@ -20,4 +20,4 @@ bar'
----------------------------------------------------
Checks for single-quoted and double-quoted strings.
Checks for single-quoted and double-quoted strings.