From afd77ed13577b80018a6179420d9f638145b08d4 Mon Sep 17 00:00:00 2001 From: Michael Schmidt Date: Tue, 7 Dec 2021 12:56:42 +0100 Subject: [PATCH] Stan: Added missing keywords and HOFs (#3238) --- components/prism-stan.js | 104 ++++++++++-------- components/prism-stan.min.js | 2 +- tests/languages/stan/keyword_feature.test | 30 ++++- tests/languages/stan/number_feature.test | 14 ++- .../stan/program-block_feature.html.test | 76 +++++++++++++ 5 files changed, 179 insertions(+), 47 deletions(-) create mode 100644 tests/languages/stan/program-block_feature.html.test diff --git a/components/prism-stan.js b/components/prism-stan.js index 43973be9b5..cab2cfe997 100644 --- a/components/prism-stan.js +++ b/components/prism-stan.js @@ -1,49 +1,65 @@ -// https://mc-stan.org/docs/2_24/reference-manual/bnf-grammars.html +(function (Prism) { -Prism.languages.stan = { - 'comment': /\/\/.*|\/\*[\s\S]*?\*\/|#(?!include).*/, - 'string': { - // String literals can contain spaces and any printable ASCII characters except for " and \ - // https://mc-stan.org/docs/2_24/reference-manual/print-statements-section.html#string-literals - pattern: /"[\x20\x21\x23-\x5B\x5D-\x7E]*"/, - greedy: true - }, - 'directive': { - pattern: /^([ \t]*)#include\b.*/m, - lookbehind: true, - alias: 'property' - }, + // https://mc-stan.org/docs/2_28/reference-manual/bnf-grammars.html - 'function-arg': { - pattern: /(\b(?:algebra_solver|integrate_1d|integrate_ode|integrate_ode_bdf|integrate_ode_rk45|map_rect)\s*\(\s*)[a-zA-Z]\w*/, - lookbehind: true, - alias: 'function' - }, - 'constraint': { - pattern: /(\b(?:int|matrix|real|row_vector|vector)\s*)<[^<>]*>/, - lookbehind: true, - inside: { - 'expression': { - pattern: /(=\s*)\S(?:\S|\s+(?!\s))*?(?=\s*(?:>$|,\s*\w+\s*=))/, - lookbehind: true, - inside: null // see below + var higherOrderFunctions = /\b(?:algebra_solver|algebra_solver_newton|integrate_1d|integrate_ode|integrate_ode_bdf|integrate_ode_rk45|map_rect|ode_(?:adams|bdf|ckrk|rk45)(?:_tol)?|ode_adjoint_tol_ctl|reduce_sum|reduce_sum_static)\b/; + + Prism.languages.stan = { + 'comment': /\/\/.*|\/\*[\s\S]*?\*\/|#(?!include).*/, + 'string': { + // String literals can contain spaces and any printable ASCII characters except for " and \ + // https://mc-stan.org/docs/2_24/reference-manual/print-statements-section.html#string-literals + pattern: /"[\x20\x21\x23-\x5B\x5D-\x7E]*"/, + greedy: true + }, + 'directive': { + pattern: /^([ \t]*)#include\b.*/m, + lookbehind: true, + alias: 'property' + }, + + 'function-arg': { + pattern: RegExp( + '(' + + higherOrderFunctions.source + + /\s*\(\s*/.source + + ')' + + /[a-zA-Z]\w*/.source + ), + lookbehind: true, + alias: 'function' + }, + 'constraint': { + pattern: /(\b(?:int|matrix|real|row_vector|vector)\s*)<[^<>]*>/, + lookbehind: true, + inside: { + 'expression': { + pattern: /(=\s*)\S(?:\S|\s+(?!\s))*?(?=\s*(?:>$|,\s*\w+\s*=))/, + lookbehind: true, + inside: null // see below + }, + 'property': /\b[a-z]\w*(?=\s*=)/i, + 'operator': /=/, + 'punctuation': /^<|>$|,/ + } + }, + 'keyword': [ + { + pattern: /\bdata(?=\s*\{)|\b(?:functions|generated|model|parameters|quantities|transformed)\b/, + alias: 'program-block' }, - 'property': /\b[a-z]\w*(?=\s*=)/i, - 'operator': /=/, - 'punctuation': /^<|>$|,/ - } - }, - 'keyword': [ - /\b(?:break|cholesky_factor_corr|cholesky_factor_cov|continue|corr_matrix|cov_matrix|data|else|for|functions|generated|if|in|increment_log_prob|int|matrix|model|ordered|parameters|positive_ordered|print|quantities|real|reject|return|row_vector|simplex|target|transformed|unit_vector|vector|void|while)\b/, - // these are functions that are known to take another function as their first argument. - /\b(?:algebra_solver|integrate_1d|integrate_ode|integrate_ode_bdf|integrate_ode_rk45|map_rect)\b/ - ], - 'function': /\b[a-z]\w*(?=\s*\()/i, - 'number': /(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:E[+-]?\d+)?\b/i, - 'boolean': /\b(?:false|true)\b/, + /\b(?:array|break|cholesky_factor_corr|cholesky_factor_cov|complex|continue|corr_matrix|cov_matrix|data|else|for|if|in|increment_log_prob|int|matrix|ordered|positive_ordered|print|real|reject|return|row_vector|simplex|target|unit_vector|vector|void|while)\b/, + // these are functions that are known to take another function as their first argument. + higherOrderFunctions + ], + 'function': /\b[a-z]\w*(?=\s*\()/i, + 'number': /(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:E[+-]?\d+(?:_\d+)*)?i?(?!\w)/i, + 'boolean': /\b(?:false|true)\b/, + + 'operator': /<-|\.[*/]=?|\|\|?|&&|[!=<>+\-*/]=?|['^%~?:]/, + 'punctuation': /[()\[\]{},;]/ + }; - 'operator': /<-|\.[*/]=?|\|\|?|&&|[!=<>+\-*/]=?|['^%~?:]/, - 'punctuation': /[()\[\]{},;]/ -}; + Prism.languages.stan.constraint.inside.expression.inside = Prism.languages.stan; -Prism.languages.stan.constraint.inside.expression.inside = Prism.languages.stan; +}(Prism)); diff --git a/components/prism-stan.min.js b/components/prism-stan.min.js index 5d4f8a0f57..5db623fab4 100644 --- a/components/prism-stan.min.js +++ b/components/prism-stan.min.js @@ -1 +1 @@ -Prism.languages.stan={comment:/\/\/.*|\/\*[\s\S]*?\*\/|#(?!include).*/,string:{pattern:/"[\x20\x21\x23-\x5B\x5D-\x7E]*"/,greedy:!0},directive:{pattern:/^([ \t]*)#include\b.*/m,lookbehind:!0,alias:"property"},"function-arg":{pattern:/(\b(?:algebra_solver|integrate_1d|integrate_ode|integrate_ode_bdf|integrate_ode_rk45|map_rect)\s*\(\s*)[a-zA-Z]\w*/,lookbehind:!0,alias:"function"},constraint:{pattern:/(\b(?:int|matrix|real|row_vector|vector)\s*)<[^<>]*>/,lookbehind:!0,inside:{expression:{pattern:/(=\s*)\S(?:\S|\s+(?!\s))*?(?=\s*(?:>$|,\s*\w+\s*=))/,lookbehind:!0,inside:null},property:/\b[a-z]\w*(?=\s*=)/i,operator:/=/,punctuation:/^<|>$|,/}},keyword:[/\b(?:break|cholesky_factor_corr|cholesky_factor_cov|continue|corr_matrix|cov_matrix|data|else|for|functions|generated|if|in|increment_log_prob|int|matrix|model|ordered|parameters|positive_ordered|print|quantities|real|reject|return|row_vector|simplex|target|transformed|unit_vector|vector|void|while)\b/,/\b(?:algebra_solver|integrate_1d|integrate_ode|integrate_ode_bdf|integrate_ode_rk45|map_rect)\b/],function:/\b[a-z]\w*(?=\s*\()/i,number:/(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:E[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,operator:/<-|\.[*/]=?|\|\|?|&&|[!=<>+\-*/]=?|['^%~?:]/,punctuation:/[()\[\]{},;]/},Prism.languages.stan.constraint.inside.expression.inside=Prism.languages.stan; \ No newline at end of file +!function(e){var r=/\b(?:algebra_solver|algebra_solver_newton|integrate_1d|integrate_ode|integrate_ode_bdf|integrate_ode_rk45|map_rect|ode_(?:adams|bdf|ckrk|rk45)(?:_tol)?|ode_adjoint_tol_ctl|reduce_sum|reduce_sum_static)\b/;e.languages.stan={comment:/\/\/.*|\/\*[\s\S]*?\*\/|#(?!include).*/,string:{pattern:/"[\x20\x21\x23-\x5B\x5D-\x7E]*"/,greedy:!0},directive:{pattern:/^([ \t]*)#include\b.*/m,lookbehind:!0,alias:"property"},"function-arg":{pattern:RegExp("("+r.source+"\\s*\\(\\s*)[a-zA-Z]\\w*"),lookbehind:!0,alias:"function"},constraint:{pattern:/(\b(?:int|matrix|real|row_vector|vector)\s*)<[^<>]*>/,lookbehind:!0,inside:{expression:{pattern:/(=\s*)\S(?:\S|\s+(?!\s))*?(?=\s*(?:>$|,\s*\w+\s*=))/,lookbehind:!0,inside:null},property:/\b[a-z]\w*(?=\s*=)/i,operator:/=/,punctuation:/^<|>$|,/}},keyword:[{pattern:/\bdata(?=\s*\{)|\b(?:functions|generated|model|parameters|quantities|transformed)\b/,alias:"program-block"},/\b(?:array|break|cholesky_factor_corr|cholesky_factor_cov|complex|continue|corr_matrix|cov_matrix|data|else|for|if|in|increment_log_prob|int|matrix|ordered|positive_ordered|print|real|reject|return|row_vector|simplex|target|unit_vector|vector|void|while)\b/,r],function:/\b[a-z]\w*(?=\s*\()/i,number:/(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:E[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,boolean:/\b(?:false|true)\b/,operator:/<-|\.[*/]=?|\|\|?|&&|[!=<>+\-*/]=?|['^%~?:]/,punctuation:/[()\[\]{},;]/},e.languages.stan.constraint.inside.expression.inside=e.languages.stan}(Prism); \ No newline at end of file diff --git a/tests/languages/stan/keyword_feature.test b/tests/languages/stan/keyword_feature.test index fb1613ab10..139941870e 100644 --- a/tests/languages/stan/keyword_feature.test +++ b/tests/languages/stan/keyword_feature.test @@ -1,6 +1,8 @@ +array break cholesky_factor_corr cholesky_factor_cov +complex continue corr_matrix cov_matrix @@ -33,18 +35,32 @@ void while algebra_solver +algebra_solver_newton integrate_1d integrate_ode integrate_ode_bdf integrate_ode_rk45 map_rect +ode_adams +ode_adams_tol +ode_adjoint_tol_ctl +ode_bdf +ode_bdf_tol +ode_ckrk +ode_ckrk_tol +ode_rk45 +ode_rk45_tol +reduce_sum +reduce_sum_static ---------------------------------------------------- [ + ["keyword", "array"], ["keyword", "break"], ["keyword", "cholesky_factor_corr"], ["keyword", "cholesky_factor_cov"], + ["keyword", "complex"], ["keyword", "continue"], ["keyword", "corr_matrix"], ["keyword", "cov_matrix"], @@ -77,11 +93,23 @@ map_rect ["keyword", "while"], ["keyword", "algebra_solver"], + ["keyword", "algebra_solver_newton"], ["keyword", "integrate_1d"], ["keyword", "integrate_ode"], ["keyword", "integrate_ode_bdf"], ["keyword", "integrate_ode_rk45"], - ["keyword", "map_rect"] + ["keyword", "map_rect"], + ["keyword", "ode_adams"], + ["keyword", "ode_adams_tol"], + ["keyword", "ode_adjoint_tol_ctl"], + ["keyword", "ode_bdf"], + ["keyword", "ode_bdf_tol"], + ["keyword", "ode_ckrk"], + ["keyword", "ode_ckrk_tol"], + ["keyword", "ode_rk45"], + ["keyword", "ode_rk45_tol"], + ["keyword", "reduce_sum"], + ["keyword", "reduce_sum_static"] ] ---------------------------------------------------- diff --git a/tests/languages/stan/number_feature.test b/tests/languages/stan/number_feature.test index 0d70a28a41..4741a872a1 100644 --- a/tests/languages/stan/number_feature.test +++ b/tests/languages/stan/number_feature.test @@ -1,6 +1,7 @@ 0 1 24567898765 +24_56_78_98_765 0.0 1.0 @@ -8,6 +9,11 @@ 2.7e3 2E-5 1.23e+3 +3.14i +40e-3i +1e10i +0i +1_2.3_4e5_6i ---------------------------------------------------- @@ -15,13 +21,19 @@ ["number", "0"], ["number", "1"], ["number", "24567898765"], + ["number", "24_56_78_98_765"], ["number", "0.0"], ["number", "1.0"], ["number", "3.14"], ["number", "2.7e3"], ["number", "2E-5"], - ["number", "1.23e+3"] + ["number", "1.23e+3"], + ["number", "3.14i"], + ["number", "40e-3i"], + ["number", "1e10i"], + ["number", "0i"], + ["number", "1_2.3_4e5_6i"] ] ---------------------------------------------------- diff --git a/tests/languages/stan/program-block_feature.html.test b/tests/languages/stan/program-block_feature.html.test new file mode 100644 index 0000000000..1de0f530af --- /dev/null +++ b/tests/languages/stan/program-block_feature.html.test @@ -0,0 +1,76 @@ +functions { + // ... function declarations and definitions ... +} +data { + // ... declarations ... +} +transformed data { + // ... declarations ... statements ... +} +parameters { + // ... declarations ... +} +transformed parameters { + // ... declarations ... statements ... +} +model { + // ... declarations ... statements ... +} +generated quantities { + // ... declarations ... statements ... +} + +// data-only quantifiers +real foo(data real x) { + return x^2; +} + +---------------------------------------------------- + +functions +{ +// ... function declarations and definitions ... +} +data +{ +// ... declarations ... +} +transformed +data +{ +// ... declarations ... statements ... +} +parameters +{ +// ... declarations ... +} +transformed +parameters +{ +// ... declarations ... statements ... +} +model +{ +// ... declarations ... statements ... +} +generated +quantities +{ +// ... declarations ... statements ... +} + +// data-only quantifiers +real +foo +( +data +real +x +) +{ +return +x +^ +2 +; +}