Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/pygments/lexers/modeling.py: 79%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

61 statements  

1""" 

2 pygments.lexers.modeling 

3 ~~~~~~~~~~~~~~~~~~~~~~~~ 

4 

5 Lexers for modeling languages. 

6 

7 :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS. 

8 :license: BSD, see LICENSE for details. 

9""" 

10 

11import re 

12 

13from pygments.lexer import RegexLexer, include, bygroups, using, default 

14from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ 

15 Number, Punctuation, Whitespace 

16 

17from pygments.lexers.html import HtmlLexer 

18from pygments.lexers import _stan_builtins 

19 

20__all__ = ['ModelicaLexer', 'BugsLexer', 'JagsLexer', 'StanLexer'] 

21 

22 

23class ModelicaLexer(RegexLexer): 

24 """ 

25 For Modelica source code. 

26 """ 

27 name = 'Modelica' 

28 url = 'http://www.modelica.org/' 

29 aliases = ['modelica'] 

30 filenames = ['*.mo'] 

31 mimetypes = ['text/x-modelica'] 

32 version_added = '1.1' 

33 

34 flags = re.DOTALL | re.MULTILINE 

35 

36 _name = r"(?:'(?:[^\\']|\\.)+'|[a-zA-Z_]\w*)" 

37 

38 tokens = { 

39 'whitespace': [ 

40 (r'[\s\ufeff]+', Text), 

41 (r'//[^\n]*\n?', Comment.Single), 

42 (r'/\*.*?\*/', Comment.Multiline) 

43 ], 

44 'root': [ 

45 include('whitespace'), 

46 (r'"', String.Double, 'string'), 

47 (r'[()\[\]{},;]+', Punctuation), 

48 (r'\.?[*^/+-]|\.|<>|[<>:=]=?', Operator), 

49 (r'\d+(\.?\d*[eE][-+]?\d+|\.\d*)', Number.Float), 

50 (r'\d+', Number.Integer), 

51 (r'(abs|acos|actualStream|array|asin|assert|AssertionLevel|atan|' 

52 r'atan2|backSample|Boolean|cardinality|cat|ceil|change|Clock|' 

53 r'Connections|cos|cosh|cross|delay|diagonal|div|edge|exp|' 

54 r'ExternalObject|fill|floor|getInstanceName|hold|homotopy|' 

55 r'identity|inStream|integer|Integer|interval|inverse|isPresent|' 

56 r'linspace|log|log10|matrix|max|min|mod|ndims|noClock|noEvent|' 

57 r'ones|outerProduct|pre|previous|product|Real|reinit|rem|rooted|' 

58 r'sample|scalar|semiLinear|shiftSample|sign|sin|sinh|size|skew|' 

59 r'smooth|spatialDistribution|sqrt|StateSelect|String|subSample|' 

60 r'sum|superSample|symmetric|tan|tanh|terminal|terminate|time|' 

61 r'transpose|vector|zeros)\b', Name.Builtin), 

62 (r'(algorithm|annotation|break|connect|constant|constrainedby|der|' 

63 r'discrete|each|else|elseif|elsewhen|encapsulated|enumeration|' 

64 r'equation|exit|expandable|extends|external|firstTick|final|flow|for|if|' 

65 r'import|impure|in|initial|inner|input|interval|loop|nondiscrete|outer|' 

66 r'output|parameter|partial|protected|public|pure|redeclare|' 

67 r'replaceable|return|stream|then|when|while)\b', 

68 Keyword.Reserved), 

69 (r'(and|not|or)\b', Operator.Word), 

70 (r'(block|class|connector|end|function|model|operator|package|' 

71 r'record|type)\b', Keyword.Reserved, 'class'), 

72 (r'(false|true)\b', Keyword.Constant), 

73 (r'within\b', Keyword.Reserved, 'package-prefix'), 

74 (_name, Name) 

75 ], 

76 'class': [ 

77 include('whitespace'), 

78 (r'(function|record)\b', Keyword.Reserved), 

79 (r'(if|for|when|while)\b', Keyword.Reserved, '#pop'), 

80 (_name, Name.Class, '#pop'), 

81 default('#pop') 

82 ], 

83 'package-prefix': [ 

84 include('whitespace'), 

85 (_name, Name.Namespace, '#pop'), 

86 default('#pop') 

87 ], 

88 'string': [ 

89 (r'"', String.Double, '#pop'), 

90 (r'\\[\'"?\\abfnrtv]', String.Escape), 

91 (r'(?i)<\s*html\s*>([^\\"]|\\.)+?(<\s*/\s*html\s*>|(?="))', 

92 using(HtmlLexer)), 

93 (r'<|\\?[^"\\<]+', String.Double) 

94 ] 

95 } 

96 

97 

98class BugsLexer(RegexLexer): 

99 """ 

100 Pygments Lexer for OpenBugs and WinBugs 

101 models. 

102 """ 

103 

104 name = 'BUGS' 

105 aliases = ['bugs', 'winbugs', 'openbugs'] 

106 filenames = ['*.bug'] 

107 url = 'https://www.mrc-bsu.cam.ac.uk/software/bugs/openbugs' 

108 version_added = '1.6' 

109 

110 _FUNCTIONS = ( 

111 # Scalar functions 

112 'abs', 'arccos', 'arccosh', 'arcsin', 'arcsinh', 'arctan', 'arctanh', 

113 'cloglog', 'cos', 'cosh', 'cumulative', 'cut', 'density', 'deviance', 

114 'equals', 'expr', 'gammap', 'ilogit', 'icloglog', 'integral', 'log', 

115 'logfact', 'loggam', 'logit', 'max', 'min', 'phi', 'post.p.value', 

116 'pow', 'prior.p.value', 'probit', 'replicate.post', 'replicate.prior', 

117 'round', 'sin', 'sinh', 'solution', 'sqrt', 'step', 'tan', 'tanh', 

118 'trunc', 

119 # Vector functions 

120 'inprod', 'interp.lin', 'inverse', 'logdet', 'mean', 'eigen.vals', 

121 'ode', 'prod', 'p.valueM', 'rank', 'ranked', 'replicate.postM', 

122 'sd', 'sort', 'sum', 

123 # Special 

124 'D', 'I', 'F', 'T', 'C') 

125 """ OpenBUGS built-in functions 

126 

127 From http://www.openbugs.info/Manuals/ModelSpecification.html#ContentsAII 

128 

129 This also includes 

130 

131 - T, C, I : Truncation and censoring. 

132 ``T`` and ``C`` are in OpenBUGS. ``I`` in WinBUGS. 

133 - D : ODE 

134 - F : Functional http://www.openbugs.info/Examples/Functionals.html 

135 

136 """ 

137 

138 _DISTRIBUTIONS = ('dbern', 'dbin', 'dcat', 'dnegbin', 'dpois', 

139 'dhyper', 'dbeta', 'dchisqr', 'ddexp', 'dexp', 

140 'dflat', 'dgamma', 'dgev', 'df', 'dggamma', 'dgpar', 

141 'dloglik', 'dlnorm', 'dlogis', 'dnorm', 'dpar', 

142 'dt', 'dunif', 'dweib', 'dmulti', 'ddirch', 'dmnorm', 

143 'dmt', 'dwish') 

144 """ OpenBUGS built-in distributions 

145 

146 Functions from 

147 http://www.openbugs.info/Manuals/ModelSpecification.html#ContentsAI 

148 """ 

149 

150 tokens = { 

151 'whitespace': [ 

152 (r"\s+", Text), 

153 ], 

154 'comments': [ 

155 # Comments 

156 (r'#.*$', Comment.Single), 

157 ], 

158 'root': [ 

159 # Comments 

160 include('comments'), 

161 include('whitespace'), 

162 # Block start 

163 (r'(model)(\s+)(\{)', 

164 bygroups(Keyword.Namespace, Text, Punctuation)), 

165 # Reserved Words 

166 (r'(for|in)(?![\w.])', Keyword.Reserved), 

167 # Built-in Functions 

168 (r'({})(?=\s*\()'.format(r'|'.join(_FUNCTIONS + _DISTRIBUTIONS)), 

169 Name.Builtin), 

170 # Regular variable names 

171 (r'[A-Za-z][\w.]*', Name), 

172 # Number Literals 

173 (r'[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?', Number), 

174 # Punctuation 

175 (r'\[|\]|\(|\)|:|,|;', Punctuation), 

176 # Assignment operators 

177 # SLexer makes these tokens Operators. 

178 (r'<-|~', Operator), 

179 # Infix and prefix operators 

180 (r'\+|-|\*|/', Operator), 

181 # Block 

182 (r'[{}]', Punctuation), 

183 ] 

184 } 

185 

186 def analyse_text(text): 

187 if re.search(r"^\s*model\s*{", text, re.M): 

188 return 0.7 

189 else: 

190 return 0.0 

191 

192 

193class JagsLexer(RegexLexer): 

194 """ 

195 Pygments Lexer for JAGS. 

196 """ 

197 

198 name = 'JAGS' 

199 aliases = ['jags'] 

200 filenames = ['*.jag', '*.bug'] 

201 url = 'https://mcmc-jags.sourceforge.io' 

202 version_added = '1.6' 

203 

204 # JAGS 

205 _FUNCTIONS = ( 

206 'abs', 'arccos', 'arccosh', 'arcsin', 'arcsinh', 'arctan', 'arctanh', 

207 'cos', 'cosh', 'cloglog', 

208 'equals', 'exp', 'icloglog', 'ifelse', 'ilogit', 'log', 'logfact', 

209 'loggam', 'logit', 'phi', 'pow', 'probit', 'round', 'sin', 'sinh', 

210 'sqrt', 'step', 'tan', 'tanh', 'trunc', 'inprod', 'interp.lin', 

211 'logdet', 'max', 'mean', 'min', 'prod', 'sum', 'sd', 'inverse', 

212 'rank', 'sort', 't', 'acos', 'acosh', 'asin', 'asinh', 'atan', 

213 # Truncation/Censoring (should I include) 

214 'T', 'I') 

215 # Distributions with density, probability and quartile functions 

216 _DISTRIBUTIONS = tuple(f'[dpq]{x}' for x in 

217 ('bern', 'beta', 'dchiqsqr', 'ddexp', 'dexp', 

218 'df', 'gamma', 'gen.gamma', 'logis', 'lnorm', 

219 'negbin', 'nchisqr', 'norm', 'par', 'pois', 'weib')) 

220 # Other distributions without density and probability 

221 _OTHER_DISTRIBUTIONS = ( 

222 'dt', 'dunif', 'dbetabin', 'dbern', 'dbin', 'dcat', 'dhyper', 

223 'ddirch', 'dmnorm', 'dwish', 'dmt', 'dmulti', 'dbinom', 'dchisq', 

224 'dnbinom', 'dweibull', 'ddirich') 

225 

226 tokens = { 

227 'whitespace': [ 

228 (r"\s+", Text), 

229 ], 

230 'names': [ 

231 # Regular variable names 

232 (r'[a-zA-Z][\w.]*\b', Name), 

233 ], 

234 'comments': [ 

235 # do not use stateful comments 

236 (r'(?s)/\*.*?\*/', Comment.Multiline), 

237 # Comments 

238 (r'#.*$', Comment.Single), 

239 ], 

240 'root': [ 

241 # Comments 

242 include('comments'), 

243 include('whitespace'), 

244 # Block start 

245 (r'(model|data)(\s+)(\{)', 

246 bygroups(Keyword.Namespace, Text, Punctuation)), 

247 (r'var(?![\w.])', Keyword.Declaration), 

248 # Reserved Words 

249 (r'(for|in)(?![\w.])', Keyword.Reserved), 

250 # Builtins 

251 # Need to use lookahead because . is a valid char 

252 (r'({})(?=\s*\()'.format(r'|'.join(_FUNCTIONS 

253 + _DISTRIBUTIONS 

254 + _OTHER_DISTRIBUTIONS)), 

255 Name.Builtin), 

256 # Names 

257 include('names'), 

258 # Number Literals 

259 (r'[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?', Number), 

260 (r'\[|\]|\(|\)|:|,|;', Punctuation), 

261 # Assignment operators 

262 (r'<-|~', Operator), 

263 # # JAGS includes many more than OpenBUGS 

264 (r'\+|-|\*|\/|\|\|[&]{2}|[<>=]=?|\^|%.*?%', Operator), 

265 (r'[{}]', Punctuation), 

266 ] 

267 } 

268 

269 def analyse_text(text): 

270 if re.search(r'^\s*model\s*\{', text, re.M): 

271 if re.search(r'^\s*data\s*\{', text, re.M): 

272 return 0.9 

273 elif re.search(r'^\s*var', text, re.M): 

274 return 0.9 

275 else: 

276 return 0.3 

277 else: 

278 return 0 

279 

280 

281class StanLexer(RegexLexer): 

282 """Pygments Lexer for Stan models. 

283 

284 The Stan modeling language is specified in the *Stan Modeling Language 

285 User's Guide and Reference Manual, v2.17.0*, 

286 `pdf <https://github.com/stan-dev/stan/releases/download/v2.17.0/stan-reference-2.17.0.pdf>`__. 

287 """ 

288 

289 name = 'Stan' 

290 aliases = ['stan'] 

291 filenames = ['*.stan'] 

292 url = 'https://mc-stan.org' 

293 version_added = '1.6' 

294 

295 tokens = { 

296 'whitespace': [ 

297 (r"\s+", Text), 

298 ], 

299 'comments': [ 

300 (r'(?s)/\*.*?\*/', Comment.Multiline), 

301 # Comments 

302 (r'(//|#).*$', Comment.Single), 

303 ], 

304 'root': [ 

305 (r'"[^"]*"', String), 

306 # Comments 

307 include('comments'), 

308 # block start 

309 include('whitespace'), 

310 # Block start 

311 (r'({})(\s*)(\{{)'.format(r'|'.join(('functions', 'data', r'transformed\s+?data', 

312 'parameters', r'transformed\s+parameters', 

313 'model', r'generated\s+quantities'))), 

314 bygroups(Keyword.Namespace, Text, Punctuation)), 

315 # target keyword 

316 (r'target\s*\+=', Keyword), 

317 # Reserved Words 

318 (r'({})\b'.format(r'|'.join(_stan_builtins.KEYWORDS)), Keyword), 

319 # Truncation 

320 (r'T(?=\s*\[)', Keyword), 

321 # Data types 

322 (r'({})\b'.format(r'|'.join(_stan_builtins.TYPES)), Keyword.Type), 

323 # < should be punctuation, but elsewhere I can't tell if it is in 

324 # a range constraint 

325 (r'(<)(\s*)(upper|lower|offset|multiplier)(\s*)(=)', 

326 bygroups(Operator, Whitespace, Keyword, Whitespace, Punctuation)), 

327 (r'(,)(\s*)(upper)(\s*)(=)', 

328 bygroups(Punctuation, Whitespace, Keyword, Whitespace, Punctuation)), 

329 # Punctuation 

330 (r"[;,\[\]()]", Punctuation), 

331 # Builtin 

332 (r'({})(?=\s*\()'.format('|'.join(_stan_builtins.FUNCTIONS)), Name.Builtin), 

333 (r'(~)(\s*)({})(?=\s*\()'.format('|'.join(_stan_builtins.DISTRIBUTIONS)), 

334 bygroups(Operator, Whitespace, Name.Builtin)), 

335 # Special names ending in __, like lp__ 

336 (r'[A-Za-z]\w*__\b', Name.Builtin.Pseudo), 

337 (r'({})\b'.format(r'|'.join(_stan_builtins.RESERVED)), Keyword.Reserved), 

338 # user-defined functions 

339 (r'[A-Za-z]\w*(?=\s*\()]', Name.Function), 

340 # Imaginary Literals 

341 (r'[0-9]+(\.[0-9]*)?([eE][+-]?[0-9]+)?i', Number.Float), 

342 (r'\.[0-9]+([eE][+-]?[0-9]+)?i', Number.Float), 

343 (r'[0-9]+i', Number.Float), 

344 # Real Literals 

345 (r'[0-9]+(\.[0-9]*)?([eE][+-]?[0-9]+)?', Number.Float), 

346 (r'\.[0-9]+([eE][+-]?[0-9]+)?', Number.Float), 

347 # Integer Literals 

348 (r'[0-9]+', Number.Integer), 

349 # Regular variable names 

350 (r'[A-Za-z]\w*\b', Name), 

351 # Assignment operators 

352 (r'<-|(?:\+|-|\.?/|\.?\*|=)?=|~', Operator), 

353 # Infix, prefix and postfix operators (and = ) 

354 (r"\+|-|\.?\*|\.?/|\\|'|\.?\^|!=?|<=?|>=?|\|\||&&|%|\?|:|%/%|!", Operator), 

355 # Block delimiters 

356 (r'[{}]', Punctuation), 

357 # Distribution | 

358 (r'\|', Punctuation) 

359 ] 

360 } 

361 

362 def analyse_text(text): 

363 if re.search(r'^\s*parameters\s*\{', text, re.M): 

364 return 1.0 

365 else: 

366 return 0.0