monarch.html 166 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  5. <meta name="viewport" content="width=device-width" />
  6. <title>Monaco Editor Monarch</title>
  7. <link data-inline="yes-please" href="./lib/bootstrap-cosmo.css" rel="stylesheet" />
  8. <link data-inline="yes-please" href="./lib/bootstrap-responsive.min.css" rel="stylesheet" />
  9. <link data-inline="yes-please" href="./all.css" rel="stylesheet" type="text/css" />
  10. <link data-inline="yes-please" href="./monarch/monarch.css" rel="stylesheet" />
  11. <link
  12. data-name="vs/editor/editor.main"
  13. rel="stylesheet"
  14. href="../release/dev/vs/editor/editor.main.css"
  15. />
  16. </head>
  17. <body>
  18. <nav class="navbar navbar-inverse navbar-fixed-top">
  19. <div class="navbar-inner">
  20. <div class="container">
  21. <div class="logo">
  22. <a href="index.html">Monaco Editor</a>
  23. </div>
  24. <!-- collapse button for smaller screens -->
  25. <button
  26. type="button"
  27. class="btn btn-navbar"
  28. data-toggle="collapse"
  29. data-target=".nav-collapse"
  30. >
  31. <span class="icon-bar"></span>
  32. <span class="icon-bar"></span>
  33. <span class="icon-bar"></span>
  34. </button>
  35. <!-- navbar title -->
  36. <div class="nav-collapse collapse">
  37. <ul class="nav">
  38. <li><a class="nav-item" href="index.html">Home</a></li>
  39. <li><a class="nav-item" href="api/index.html">API Doc</a></li>
  40. <li><a class="nav-item" href="playground.html">Playground</a></li>
  41. <li><a class="nav-item" href="monarch.html">Monarch</a></li>
  42. <li>
  43. <a
  44. class="nav-item"
  45. target="_blank"
  46. href="https://registry.npmjs.org/monaco-editor/-/monaco-editor-{{version}}.tgz"
  47. >Download {{version}}</a
  48. >
  49. </li>
  50. </ul>
  51. </div>
  52. </div>
  53. </div>
  54. </nav>
  55. <section id="monarch">
  56. <!--******************************************
  57. Main elements
  58. **********************************************-->
  59. <div id="main">
  60. <div id="header">
  61. <img src="monarch/monarch-34px.png" id="logo" alt="Monarch-Logo" />Monarch Documentation
  62. </div>
  63. <div id="leftPane">
  64. <div class="paneheader">
  65. Language syntax definition
  66. <span class="selectbox">
  67. Sample:
  68. <select id="sampleselect">
  69. <option>mylang</option>
  70. <option>java</option>
  71. <option>javascript</option>
  72. <option>python</option>
  73. <option>csharp</option>
  74. <option>xdot</option>
  75. <option>koka</option>
  76. <option disabled label=" "></option>
  77. <option>boogie</option>
  78. <option>chalice</option>
  79. <option>dafny</option>
  80. <option>formula</option>
  81. <option>smt2</option>
  82. <option>specsharp</option>
  83. <option>z3python</option>
  84. <option disabled label=" "></option>
  85. <option>html</option>
  86. <option>markdown</option>
  87. <option>ruby</option>
  88. </select>
  89. </span>
  90. </div>
  91. <div id="langPane"></div>
  92. <div id="commandbar">Generate:</div>
  93. </div>
  94. <div id="rightPane">
  95. <div class="paneheader">
  96. Language editor
  97. <span class="arrowdown" style="display: none">&#x25BC;</span>
  98. <span class="selectbox">
  99. Theme:
  100. <select id="themeselect">
  101. <option>vs</option>
  102. <option>vs-dark</option>
  103. <option>hc-black</option>
  104. </select>
  105. </span>
  106. </div>
  107. <div id="editor"></div>
  108. <div id="monarchConsole"></div>
  109. </div>
  110. <!--******************************************
  111. Documentation
  112. **********************************************-->
  113. <!-- <div id="footer">
  114. Documentation <span class="arrowdown">&#x25BC;</span>
  115. </div>-->
  116. <div id="documentation">
  117. <h2>Monarch: create declarative syntax highlighters using JSON</h2>
  118. <p>
  119. This document describes how to create a syntax highlighter using the Monarch library.
  120. This library allows you to specify an efficient syntax highlighter, using a declarative
  121. lexical specification (written as a JSON value). The specification is expressive enough
  122. to specify sophisticated highlighters with complex state transitions, dynamic brace
  123. matching, auto-completion, other language embeddings, etc. as shown in the 'advanced'
  124. topic sections of this document. On a first read, it is safe to skip any section or
  125. paragraph marked as
  126. <span class="adv">(Advanced)</span> since many of the advanced features are rarely used
  127. in most language definitions.<br />
  128. &nbsp;&nbsp;&nbsp; &ndash; Daan Leijen.
  129. </p>
  130. <h2>Creating a language definition</h2>
  131. <p>
  132. A language definition is basically just a JSON value describing various properties of
  133. your language. Recognized attributes are:
  134. </p>
  135. <dl>
  136. <dt>ignoreCase</dt>
  137. <dd>
  138. (optional=<code>false</code>, boolean) Is the language case insensitive?. The regular
  139. expressions in the tokenizer use this to do case (in)sensitive matching, as well as
  140. tests in the
  141. <code>cases</code> construct.
  142. </dd>
  143. <dt>defaultToken</dt>
  144. <dd>
  145. (optional=<code>"source"</code>, string) The default token returned if nothing matches
  146. in the tokenizer. It can be convenient to set this to <code>"invalid"</code> during
  147. development of your colorizer to easily spot what is not matched yet.
  148. </dd>
  149. <dt id="brackets">brackets</dt>
  150. <dd>
  151. (optional, array of bracket definitions) This is used by the tokenizer to easily
  152. define matching braces. See
  153. <a href="#@brackets"><code class="dt">@brackets</code></a> and
  154. <a href="#bracket"><code class="dt">bracket</code></a> for more information. Each
  155. bracket definition is an array of 3 elements, or object, describing the
  156. <code>open</code> brace, the <code>close</code> brace, and the
  157. <code>token</code> class. The default definition is:
  158. <pre class="highlight">
  159. [ ['{','}','delimiter.curly'],
  160. ['[',']','delimiter.square'],
  161. ['(',')','delimiter.parenthesis'],
  162. ['&lt;','>','delimiter.angle'] ]</pre
  163. >
  164. </dd>
  165. <dt>tokenizer</dt>
  166. <dd>
  167. (required, object with states) This defines the tokenization rules &ndash; see the
  168. next section for a detailed description.
  169. </dd>
  170. </dl>
  171. <p>
  172. There are more attributes that can be specified which are described in the
  173. <a href="#moreattr">advanced attributes</a> section later in this document.
  174. </p>
  175. <h2>Creating a tokenizer</h2>
  176. <p>
  177. The <code>tokenizer</code> attribute describes how lexical analysis takes place, and how
  178. the input is divided into tokens. Each token is given a CSS class name which is used to
  179. render each token in the editor. Standard CSS token classes include:
  180. </p>
  181. <pre class="highlight">
  182. identifier entity constructor
  183. operators tag namespace
  184. keyword info-token type
  185. string warn-token predefined
  186. string.escape error-token invalid
  187. comment debug-token
  188. comment.doc regexp
  189. constant attribute
  190. delimiter .[curly,square,parenthesis,angle,array,bracket]
  191. number .[hex,octal,binary,float]
  192. variable .[name,value]
  193. meta .[content]</pre
  194. >
  195. <h3>States</h3>
  196. <p>
  197. A tokenizer consists of an object that defines states. The initial state of the
  198. tokenizer is the first state defined in the tokenizer. When a tokenizer is in a certain
  199. state, only the rules in that state will be applied. All rules are matched in order and
  200. when the first one matches its action is used to determine the token class. No further
  201. rules are tried. Therefore, it can be important to order the rules in a way that is most
  202. efficient, i.e. whitespace and identifiers first.
  203. </p>
  204. <p>
  205. <span class="adv">(Advanced)</span> A state is interpreted as dot (<code>.</code>)
  206. separated sub-states. When looking up the rules for a state, the tokenizer first tries
  207. the entire state name, and then looks at its parent until it finds a definition. For
  208. example, in our example, the states <code>"comment.block"</code> and
  209. <code>"comment.foo"</code> would both be handled by the <code>comment</code> rules.
  210. Hierarchical state names can be used to maintain complex lexer states, as shown for
  211. example in the section on <a href="#htmlembed">complex embeddings</a>.
  212. </p>
  213. <h3>Rules</h3>
  214. <p>
  215. Each state is defined as an array of rules which are used to match the input. Rules can
  216. have the following form:
  217. </p>
  218. <dl>
  219. <dt>[<em>regex</em>, <em>action</em>]</dt>
  220. <dd>
  221. Shorthand for
  222. <code>{ regex: <em>regex</em>, action: <em>action</em> }</code>
  223. </dd>
  224. <dt>[<em>regex</em>, <em>action</em>, <em>next</em>]</dt>
  225. <dd>
  226. Shorthand for
  227. <code>{ regex: <em>regex</em>, action: <em>action</em>{next: <em>next</em>} }</code>
  228. </dd>
  229. <dt>{regex: <em>regex</em>, action: <em>action</em> }</dt>
  230. <dd>
  231. When <code><em>regex</em></code> matches against the current input, then
  232. <code><em>action</em></code> is applied to set the token class. The regular expression
  233. <code><em>regex</em></code> can be either a regular expression (using
  234. <code>/<em>regex</em>/</code>), or a string representing a regular expression. If it
  235. starts with a <code>^</code> character, the expression only matches at the start of a
  236. source line. The <code>$</code> can be used to match against the end of a source line.
  237. Note that the tokenizer is not called when the end of the line is already reached, and
  238. the empty pattern <code>/$/</code> will therefore never match (but see
  239. <a href="#@eos"><code class="dt">'@eos'</code></a> too). Inside a regular expression,
  240. you can reference a string attribute named <code><em>attr</em></code> as
  241. <code>@<em>attr</em></code
  242. >, which is automatically expanded. This is used in the standard example to share the
  243. regular expression for escape sequences using <code>'@escapes'</code> inside the
  244. regular expression for characters and strings.
  245. <p>
  246. Regular expression primer: common regular expression escapes we use are
  247. <code>\d</code> for <code>[0-9]</code>, <code>\w</code> for
  248. <code>[a-zA-Z0-9_]</code>, and <code>\s</code> for <code>[ \t\r\n]</code>. The
  249. notation <code><em>regex</em>{<em>n</em>}</code> stands for
  250. <code><em>n</em></code> occurrences of <code><em>regex</em></code
  251. >. Also, we use <code>(?=<em>regex</em>)</code> for non-consuming `followed by
  252. <code><em>regex</em></code
  253. >', <code>(?!<em>regex</em>)</code> for `not followed by', and
  254. <code>(?:<em>regex</em>)</code> for a non-capturing group (i.e. cannot use
  255. <code>$<em>n</em></code> to refer to it).
  256. </p>
  257. </dd>
  258. <dt>{ include: <em>state</em> }</dt>
  259. <dd>
  260. Used for nice organization of your rules and expands to all the rules defined in
  261. <code><em>state</em></code
  262. >. This is pre-expanded and has no influence on performance. Many samples include the
  263. <code>'@whitespace'</code> state for example.
  264. </dd>
  265. </dl>
  266. <h3>Actions</h3>
  267. <p>
  268. An action determines the resulting token class. An action can have the following forms:
  269. </p>
  270. <dl>
  271. <dt><em>string</em></dt>
  272. <dd>
  273. Shorthand for <code>{ token: <em>string</em> }</code>.
  274. </dd>
  275. <dt>[<em>action1</em>,...,<em>actionN</em>]</dt>
  276. <dd>
  277. An array of N actions. This is only allowed when the regular expression consists of
  278. exactly N groups (ie. parenthesized parts). Due to the way the tokenizer works, you
  279. must define the groups in such a way that all groups appear at top-level and encompass
  280. the entire input, for example, we could define characters with an ascii code escape
  281. sequence as:
  282. <pre class="highlight">
  283. /(')(\\(?:[abnfrt]|[xX][0-9]{2}))(')/, ['string','string.escape','string']]</pre
  284. >
  285. <p>
  286. Note how we used a non-capturing group using
  287. <code>(?: )</code> in the inner group
  288. </p>
  289. </dd>
  290. <dt id="token">{ token: <em>tokenclass</em> }</dt>
  291. <dd>
  292. An object that defines the token class used with CSS rendering. Common token classes
  293. are for example
  294. <code>&apos;keyword&apos;</code>, <code>&apos;comment&apos;</code> or
  295. <code>&apos;identifier&apos;</code>. You can use a dot to use hierarchical CSS names,
  296. like <code>&apos;type.identifier&apos;</code> or
  297. <code>&apos;string.escape&apos;</code>. You can also include <code>$</code> patterns
  298. that are substituted with a captured group from the matched input or the tokenizer
  299. state. The patterns are described in the <a href="#pattern">guard section</a> of this
  300. document. There are some special token classes:
  301. <dl>
  302. <dt id="@brackets">"@brackets"</dt>
  303. <dd>or</dd>
  304. <dt>"@brackets.<em>tokenclass</em></dt>
  305. <dd>
  306. Signifies that brackets were tokenized. The token class for CSS is determined by
  307. the token class defined in the
  308. <a href="#brackets"><code>brackets</code></a> attribute (together with
  309. <code><em>tokenclass</em></code> if present). Moreover,
  310. <a href="#bracket"><code class="dt">bracket</code></a>
  311. attribute is set such that the editor is matches the braces (and does auto
  312. indentation). For example:
  313. <pre class="highlight">[/[{}()\[\]]/, '@brackets']</pre>
  314. </dd>
  315. <dt id="@rematch">"@rematch"</dt>
  316. <dd>
  317. <span class="adv">(Advanced)</span> Backs up the input and re-invokes the
  318. tokenizer. This of course only works when a state change happens too (or we go
  319. into an infinite recursion), so this is usually used in combination with the
  320. <code class="dt">next</code> attribute. This can be used for example when you are
  321. in a certain tokenizer state and want to get out when seeing certain end markers
  322. but don't want to consume them while being in that state. See also
  323. <a href="#nextEmbedded"><code class="dt">nextEmbedded</code></a
  324. >.
  325. </dd>
  326. </dl>
  327. <p>
  328. An action object can contain more fields that influence the state of a lexer. The
  329. following attributes are recognized:
  330. </p>
  331. <dl>
  332. <dt id="next">next: <em>state</em></dt>
  333. <dd>
  334. (string) If defined it pushes the current state onto the tokenizer stack and makes
  335. <code><em>state</em></code> the current state. This can be used for example to
  336. start tokenizing a block comment:
  337. <pre class="highlight">['/\\*', 'comment', '@comment' ]</pre>
  338. <p>Note that this is a shorthand for</p>
  339. <pre class="highlight">
  340. { regex: '/\\*', action: { token: 'comment', next: '@comment' } }</pre
  341. >
  342. <p>
  343. Here the matched <code>/*</code> is given the <code>"comment"</code> token
  344. class, and the tokenizer proceeds with matching the input using the rules in
  345. state <code>@comment</code>.
  346. </p>
  347. <p>
  348. There are a few special states that can be used for the
  349. <code>next</code> attribute:
  350. </p>
  351. <dl>
  352. <dt>"@pop"</dt>
  353. <dd>
  354. Pops the tokenizer stack to return to the previous state. This is used for
  355. example to return from block comment tokenizing after seeing the end marker:
  356. <pre class="highlight">['\\*/', 'comment', '@pop']</pre>
  357. </dd>
  358. <dt>"@push"</dt>
  359. <dd>
  360. Pushes the current state and continues in the current state. Nice for doing
  361. nested block comments when seeing a comment begin marker, i.e. in the
  362. <code>@comment</code> state, we can do:
  363. <pre class="highlight">['/\\*', 'comment', '@push']</pre>
  364. </dd>
  365. <dt id="popall">"@popall"</dt>
  366. <dd>
  367. Pops everything from tokenizer stack and returns to the top state. This can be
  368. used during recovery to 'jump' back to the initial state from a deep nesting
  369. level.
  370. </dd>
  371. </dl>
  372. </dd>
  373. <dt id="switchTo">switchTo: <em>state</em></dt>
  374. <dd>
  375. <span class="adv">(Advanced)</span> Switch to <code><em>state</em></code> without
  376. changing the stack.
  377. </dd>
  378. <dt id="goBack">goBack: <em>number</em></dt>
  379. <dd>
  380. <span class="adv">(Advanced)</span> Back up the input by
  381. <code><em>number</em></code> characters.
  382. </dd>
  383. <dt id="bracket">bracket: <em>kind</em></dt>
  384. <dd>
  385. <span class="adv">(Advanced)</span> The <code><em>kind</em></code> can be either
  386. <code>'@open'</code> or <code>'@close'</code>. This signifies that a token is
  387. either an open or close brace. This attribute is set automatically if the token
  388. class is <a href="#@brackets"><code class="dt">@brackets</code></a
  389. >. The editor uses the bracket information to show matching braces (where an open
  390. bracket matches with a close bracket if their token classes are the same).
  391. Moreover, when a user opens a new line the editor will do auto indentation on open
  392. braces. Normally, this attribute does not need to be set if you are using the
  393. <a href="#brackets"><code class="dt">brackets</code></a>
  394. attribute and it is only used for complex brace matching. This is discussed
  395. further in the next section on
  396. <a href="#complexmatch">advanced brace matching</a>.
  397. </dd>
  398. <dt id="nextEmbedded">nextEmbedded: <em>langId</em> <span>or</span> '@pop'</dt>
  399. <dd>
  400. <span class="adv">(Advanced)</span> Signifies to the editor that this token is
  401. followed by code in another language specified by the <code><em>langId</em></code
  402. >, i.e. for example <code>javascript</code>. Internally, our syntax highlighter
  403. keeps tokenizing the source until it finds an an ending sequence. At that point,
  404. you can use <code class="dt">nextEmbedded</code> with a
  405. <code class="dt">'@pop'</code> value to pop out of the embedded mode again.
  406. <code class="dt">nextEmbedded</code> usually needs a
  407. <code class="dt">next</code> attribute to switch to a state where we can tokenize
  408. the foreign code. As an example, here is how we could support CSS fragments in our
  409. language:
  410. <pre class="highlight">
  411. root: [
  412. [/&lt;style\s*>/, { token: 'keyword', bracket: '@open'
  413. , next: '@css_block', nextEmbedded: 'text/css' }],
  414. [/&lt;\/style\s*>/, { token: 'keyword', bracket: '@close' }],
  415. ...
  416. ],
  417. css_block: [
  418. [/[^"&lt;]+/, ''],
  419. [/&lt;\/style\s*>/, { token: '@rematch', next: '@pop', nextEmbedded: '@pop' }],
  420. [/"/, 'string', '@string' ],
  421. [/&lt;/, '']
  422. ],</pre
  423. >
  424. <p>
  425. Note how we switch to the <code>css_block</code> state for tokenizing the CSS
  426. source. Also inside the CSS we use the <code>@string</code> state to tokenize
  427. CSS strings such that we do not stop the CSS block when we find
  428. <code>&lt;/style&gt;</code> inside a string. When we find the closing tag, we
  429. also <a href="#@pop"><code class="dt">"@pop"</code></a> the state to get back to
  430. normal tokenization. Finally, we need to
  431. <a href="#@rematch"><code class="dt">"@rematch"</code></a>
  432. the token (in the <code>root</code> state) since the editor ignores our token
  433. classes until we actually exit the embedded mode. See also a later section on
  434. <a href="#htmlembed">complex dynamic embeddings</a>. (Bug: you can only start an
  435. embedded section if the you consume characters at the start of the embedded
  436. block (like consuming the <code>&lt;style&gt;</code> tag) (Aug 2012))
  437. </p>
  438. </dd>
  439. <dt id="log">log: <em>message</em></dt>
  440. <dd>
  441. Used for debugging. Logs <code><em>message</em></code> to the console window in
  442. the browser (press F12 to see it). This can be useful to see if a certain action
  443. is executing. For example:
  444. <pre class="highlight">
  445. [/\d+/, { token: 'number', log: 'found number $0 in state $S0' } ]</pre
  446. >
  447. </dd>
  448. <dd>&nbsp;</dd>
  449. <!--
  450. <dt>bracketType: <em>bracketType</em></dt><dd>If <code>token</code> is <code>"@brackets"</code>, this attribute can specify for an arbitrary matched input (like <code>"end"</code>), which is not present in the <code>brackets</code> attribute, what kind of bracket this is: <code>"@open"</code>, <code>"@close"</code>, or <code>"@none"</code>.</dd>
  451. -->
  452. </dl>
  453. </dd>
  454. <dt id="cases">
  455. { cases: { <em>guard1</em>: <em>action1</em>, ..., <em>guardN</em>: <em>actionN</em> }
  456. }
  457. </dt>
  458. <dd>
  459. The final kind of action object is a cases statement. A cases object contains an
  460. object where each field functions as a guard. Each guard is applied to the matched
  461. input and as soon as one of them matches, the corresponding action is applied. Note
  462. that since these are actions themselves, cases can be nested. Cases are used for
  463. efficiency: for example, we match for identifiers and then test whether the identifier
  464. is possibly a keyword or builtin function:
  465. <pre class="highlight">
  466. [/[a-z_\$][a-zA-Z0-9_\$]*/,
  467. { cases: { '@typeKeywords': 'keyword.type'
  468. , '@keywords': 'keyword'
  469. , '@default': 'identifier' }
  470. }
  471. ]</pre
  472. >
  473. <p>The guards can consist of:</p>
  474. <dl>
  475. <dt>"@<em>keywords</em>"</dt>
  476. <dd>
  477. The attribute <code><em>keywords</em></code> must be defined in the language
  478. object and consist of an array of strings. The guard succeeds if the matched input
  479. matches any of the strings. (Note: all cases are pre-compiled and the list is
  480. tested using efficient hash maps). <span class="adv">Advanced</span>: if the
  481. attribute refers to a single string (instead of an array) it is compiled to a
  482. regular expression which is tested against the matched input.
  483. </dd>
  484. <dt>"@default"</dt>
  485. <dd>
  486. (or <code>"@"</code> or <code>""</code>) The default guard that always succeeds.
  487. </dd>
  488. <dt id="@eos">"@eos"</dt>
  489. <dd>Succeeds if the matched input has reached the end of the line.</dd>
  490. <dt>"<em>regex</em>"</dt>
  491. <dd>
  492. If the guard does not start with a <code>@</code> (or <code>$</code>) character it
  493. is interpreted as a regular expression that is tested against the matched input.
  494. Note: the <code><em>regex</em></code> is prefixed with <code>^</code> and
  495. postfixed with <code>$</code> so it must match the matched input entirely. This
  496. can be used for example to test for specific inputs, here is an example from the
  497. Koka language which uses this to enter various tokenizer states based on the
  498. declaration:
  499. <pre class="highlight">
  500. [/[a-z](\w|\-[a-zA-Z])*/,
  501. { cases:{ '@keywords': {
  502. cases: { 'alias' : { token: 'keyword', next: '@alias-type' }
  503. , 'struct' : { token: 'keyword', next: '@struct-type' }
  504. , 'type|cotype|rectype': { token: 'keyword', next: '@type' }
  505. , 'module|as|import' : { token: 'keyword', next: '@module' }
  506. , '@default' : 'keyword' }
  507. }
  508. , '@builtins': 'predefined'
  509. , '@default' : 'identifier' }
  510. }
  511. ]
  512. </pre
  513. >
  514. <p>
  515. Note the use of nested cases to improve efficiency. Also, the library recognizes
  516. simple regular expressions like the ones above and compiles them efficiently.
  517. For example, the list of words <code>type|cotype|rectype</code> is tested using
  518. a Javascript hashmap/object.
  519. </p>
  520. </dd>
  521. </dl>
  522. <p id="pattern">
  523. <span class="adv">(Advanced)</span> In general, a guard has the form
  524. <code class="dt">[<em>pat</em>][<em>op</em>]<em>match</em></code
  525. >, with an optional pattern, and operator (which are <code>$#</code> and
  526. <code>~</code> by default). The pattern can be any of:
  527. </p>
  528. <dl>
  529. <dt>$#</dt>
  530. <dd>
  531. (default) The matched input (or the group that matched when the action is an
  532. array).
  533. </dd>
  534. <dt>$<em>n</em></dt>
  535. <dd>
  536. The <em>n</em>th group of the matched input, or the entire matched input for
  537. <code>$0</code>.
  538. </dd>
  539. <dt>$S<em>n</em></dt>
  540. <dd>
  541. The <em>n</em>th part of the state, i.e. <code>$S2</code> returns
  542. <code>foo</code> in a state <code>@tag.foo</code>. Use <code>$S0</code> for the
  543. full state name.
  544. </dd>
  545. </dl>
  546. <p>
  547. The above patterns can actually occur in many attributes and are automatically
  548. expanded. Attributes where these patterns expand are
  549. <a href="#token"><code class="dt">token</code></a
  550. >, <a href="#next"><code class="dt">next</code></a
  551. >, <a href="#nextEmbedded"><code class="dt">nextEmbedded</code></a
  552. >, <a href="#switchTo"><code class="dt">switchTo</code></a
  553. >, and <a href="#log"><code class="dt">log</code></a
  554. >. Also, these patterns are expanded in the
  555. <code class="dt"><em>match</em></code> part of a guard.
  556. </p>
  557. <p>
  558. The guard operator <code><em>op</em></code> and <code><em>match</em></code> can be
  559. any of:
  560. </p>
  561. <dl>
  562. <dt>~<em>regex</em> <span style="color: black">or</span> !~<em>regex</em></dt>
  563. <dd>
  564. (default for <code><em>op</em></code> is <code>~</code>) Tests
  565. <code><em>pat</em></code> against the regular expression or its negation.
  566. </dd>
  567. <dt>
  568. @<em>attribute</em> <span style="color: black">or</span> !@<em>attribute</em>
  569. </dt>
  570. <dd>
  571. Tests whether <code><em>pat</em></code> is an element (<code>@</code>), or not an
  572. element (<code>!@</code>), of an array of strings defined by
  573. <code><em>attribute</em></code
  574. >.
  575. </dd>
  576. <dt>==<em>str</em> <span style="color: black">or</span> !=<em>str</em></dt>
  577. <dd>
  578. Tests if <code><em>pat</em></code> is equal or unequal to the given string
  579. <code><em>str</em></code
  580. >.
  581. </dd>
  582. </dl>
  583. <p>
  584. For example, here is how to check if the second group is not equal to
  585. <code>foo</code> or <code>bar</code>: <code>$2!~foo|bar</code>, or if the first
  586. captured group equals the name of the current lexer state: <code>$1==$S0</code>.
  587. </p>
  588. <p>
  589. If both <code><em>op</em></code> and <code><em>match</em></code> are empty and there
  590. is just a pattern, then the guard succeeds if the pattern is non-empty. This can be
  591. used for example to improve efficiency. In the Koka language, an upper case
  592. identifier followed by a dot is module name, but without the following dot it is a
  593. constructor. This can be matched for in one go using:
  594. </p>
  595. <pre class="highlight">
  596. [/([A-Z](?:[a-zA-Z0-9_]|\-[a-zA-Z])*)(\.?)/,
  597. { cases: { '$2' : ['identifier.namespace','keyword.dot']
  598. , '@default': 'identifier.constructor' }}
  599. ]</pre
  600. >
  601. </dd>
  602. </dl>
  603. <p>&nbsp;</p>
  604. <h2 id="complexmatch">Advanced: complex brace matching</h2>
  605. <p>
  606. This section gives some advanced examples of brace matching using the
  607. <a href="#bracket"><code class="dt">bracket</code></a> attribute in an action. Usually,
  608. we can match braces just using the
  609. <a href="#brackets"><code>brackets</code></a> attribute in combination with the
  610. <a href="#@brackets"><code>@brackets</code></a> token class. But sometimes we need more
  611. fine grained control. For example, in Ruby many declarations like
  612. <code class="token keyword">class</code> or <code class="token keyword">def</code> are
  613. ended with the <code class="token keyword">end</code> keyword. To make them match, we
  614. all give them the same token class (<code>keyword.decl</code>) and use bracket
  615. <code>@close</code> for <code class="token keyword">end</code> and
  616. <code>@open</code> for all declarations:
  617. </p>
  618. <pre class="highlight">
  619. declarations: ['class','def','module', ... ]
  620. tokenizer: {
  621. root: {
  622. [/[a-zA-Z]\w*/,
  623. { cases: { 'end' : { token: 'keyword.decl', bracket: '@close' }
  624. , '@declarations': { token: 'keyword.decl', bracket: '@open' }
  625. , '@keywords' : 'keyword'
  626. , '@default' : 'identifier' }
  627. }
  628. ],</pre
  629. >
  630. <p>
  631. Note that to make <em>outdentation</em> work on the <code>end</code> keyword, you would
  632. also need to include the <code>'d'</code> character in the
  633. <a href="#outdentTriggers"><code class="dt">outdentTriggers</code></a>
  634. string.
  635. </p>
  636. <p>
  637. Another example of complex matching is HTML where we would like to match starting tags,
  638. like <code>&lt;div&gt;</code> with an ending tag <code>&lt;/div&gt;</code>. To make an
  639. end tag only match its specific open tag, we need to dynamically generate token classes
  640. that make the braces match correctly. This can be done using <code>$</code> expansion in
  641. the token class:
  642. </p>
  643. <pre class="highlight">
  644. tokenizer: {
  645. root: {
  646. [/&lt;(\w+)(>?)/, { token: 'tag-$1', bracket: '@open' }],
  647. [/&lt;\/(\w+)\s*>/, { token: 'tag-$1', bracket: '@close' }],</pre
  648. >
  649. <p>
  650. Note how we captured the actual tag name as a group and used that to generate the right
  651. token class. Again, to make outdentation work on the closing tag, you would also need to
  652. include the
  653. <code>'>'</code> character in the
  654. <a href="#outdentTriggers"><code class="dt">outdentTriggers</code></a>
  655. string.
  656. </p>
  657. <p>
  658. A final advanced example of brace matching is Visual Basic where declarations like
  659. <code class="token keyword">Structure</code> are matched with end declarations as
  660. <code class="token keyword">End Structure</code>. Just like HTML we need to dynamically
  661. set token classes so that an <code class="token keyword">End Enum</code> does not match
  662. with a <code class="token keyword">Structure</code>. A tricky part is that we now need
  663. to match multiple tokens at once, and we match a construct like
  664. <code class="token keyword">End Enum</code> as one closing token, but non declaration
  665. endings, like
  666. <code class="token keyword">End</code>
  667. <code class="token constructor"> Foo</code>, as three tokens:
  668. </p>
  669. <pre class="highlight">
  670. decls: ["Structure","Class","Enum","Function",...],
  671. tokenizer: {
  672. root: {
  673. [/(End)(\s+)([A-Z]\w*)/, { cases: { '$3@decls': { token: 'keyword.decl-$3', bracket: '@close'},
  674. '@default': ['keyword','white','identifier.invalid'] }}],
  675. [/[A-Z]\w*/, { cases: { '@decls' : { token: 'keyword.decl-$0', bracket: '@open' },
  676. '@default': 'constructor' } }],</pre
  677. >
  678. <p>
  679. Note how we used <code>$3</code> to first test if the third group is a declaration, and
  680. then use <code>$3</code> in the <code>token</code> attribute to generate a declaration
  681. specific token class (so we match correctly). Also, to make outdentation work correctly,
  682. we would need to include all the ending characters of the declarations in the
  683. <a href="#outdentTriggers"><code class="dt">outdentTriggers</code></a>
  684. string.
  685. </p>
  686. <p>&nbsp;</p>
  687. <h2 id="moreattr">Advanced: more attributes on the language definition</h2>
  688. <p>Here are more advanced attributes that can be defined in the language definition:</p>
  689. <dl>
  690. <dt>tokenPostfix</dt>
  691. <dd>
  692. (optional=<code>"." + name</code>, string) Optional postfix attached to all returned
  693. tokens. By default this attaches the language name so in the CSS you can refer to your
  694. specific language. For example, for the Java language, we could use
  695. <code>.identifier.java</code> to target all Java identifiers specifically in CSS.
  696. </dd>
  697. <dt>start</dt>
  698. <dd>
  699. (optional, string) The start state of the tokenizer. By default, this is the first
  700. entry in the tokenizer attribute.
  701. </dd>
  702. <dt id="outdentTriggers">outdentTriggers</dt>
  703. <dd>
  704. (optional, string) Optional string that defines characters that when typed could cause
  705. <em>outdentation</em>. This attribute is only used when using advanced brace matching
  706. in combination with the
  707. <a href="#bracket"><code class="dt">bracket</code></a> attribute. By default it always
  708. includes the last characters of the closing brackets in the
  709. <a href="#brackets"><code class="dt">brackets</code></a> list. Outdentation happens
  710. when the user types a closing bracket word on an line that starts with only white
  711. space. If the closing bracket matches a open bracket it is indented to the same amount
  712. of that bracket. Usually, this causes the bracket to outdent. For example, in the Ruby
  713. language, the <code class="token keyword">end</code> keyword would match with an open
  714. declaration like <code class="token keyword">def</code> or
  715. <code class="token keyword">class</code>. To make outdentation happen though, we would
  716. need to include the <code>d</code> character in the
  717. <a href="#outdentTriggers"><code class="dt">outdentTriggers</code></a>
  718. attribute so it is checked when the users type
  719. <code class="token keyword">end</code>:
  720. <pre class="highlight">outdentTriggers: 'd',</pre>
  721. </dd>
  722. </dl>
  723. <p>&nbsp;</p>
  724. <h2 id="htmlembed">&Uuml;ber Advanced: complex embeddings with dynamic end tags</h2>
  725. <p>
  726. Many times, embedding other language fragments is easy as shown in the earlier CSS
  727. example, but sometimes it is more dynamic. For example, in HTML we would like to start
  728. embeddings on a
  729. <code class="token tag html">script</code> tag and
  730. <code class="token tag html">style</code> tag. By default, the script language is
  731. <code>javascript</code> but if the <code class="token key js">type</code> attribute is
  732. set, that defines the script language mime type. First, we define general tag open and
  733. close rules:
  734. </p>
  735. <pre class="highlight">
  736. [/&lt;(\w+)/, { token: 'tag.tag-$1', bracket: '@open', next: '@tag.$1' }],
  737. [/&lt;\/(\w+)\s*>/, { token: 'tag.tag-$1', bracket: '@close' } ],</pre
  738. >
  739. <p>
  740. Here, we use the <code>$1</code> to capture the open tag name in both the token class
  741. and the next state. By putting the tag name in the token class, the brace matching will
  742. match and auto indent corresponding tags automatically. Next we define the
  743. <code>@tag</code> state that matches content within an HTML tag. Because the open tag
  744. rule will set the next state to <code>@tag.<em>tagname</em></code
  745. >, this will match the <code>@tag</code> state due to dot seperation.
  746. </p>
  747. <pre class="highlight">
  748. tag: [
  749. [/[ \t\r\n]+/, 'white'],
  750. [/(type)(\s*=\s*)(['"])([^'"]+)(['"])/, [ 'attribute', 'delimiter', 'string', // todo: should match up quotes properly
  751. {token: 'string', switchTo: '@tag.$S2.$4' },
  752. 'string'] ],
  753. [/(\w+)(\s*=\s*)(['"][^'"]+['"])/, ['keyword', 'delimiter', 'string' ]],
  754. [/>/, { cases: { '$S2==style' : { token: 'delimiter', switchTo: '@embedded.$S2', nextEmbedded: 'text/css'}
  755. , '$S2==script': { cases: { '$S3' : { token: 'delimiter', switchTo: '@embedded.$S2', nextEmbedded: '$S3' },
  756. '@default': { token: 'delimiter', switchTo: '@embedded.$S2', nextEmbedded: 'javascript' } }
  757. , '@default' : { token: 'delimiter', next: '@pop' } } }]
  758. [/[^>]/,''] // catch all
  759. ],</pre
  760. >
  761. <p>
  762. Inside the <code>@tag.<em>tagname</em></code> state, we access the
  763. <code><em>tagname</em></code> through <code>$S2</code>. This is used to test if the tag
  764. name matches a script of style tag, in which case we start an embedded mode. We also
  765. need <a href="#switchTo"><code class="dt">switchTo</code></a> here since we do not want
  766. to get back to the <code>@tag</code> state at that point. Also, on a
  767. <code class="token key js">type</code> attribute we extend the state to
  768. <code>@tag.<em>tagname</em>.<em>mimetype</em></code> which allows us to access the mime
  769. type as <code>$S3</code> if it was set. This is used to determine the script language
  770. (or default to <code>javascript</code>). Finally, the script and style start an embedded
  771. mode and switch to a state <code>@embedded.<em>tagname</em></code
  772. >. The tag name is included in the state so we can scan for exactly a matching end tag:
  773. </p>
  774. <pre class="highlight">
  775. embedded: [
  776. [/[^"&lt;]+/, ''],
  777. [/&lt;\/(\w+)\s*>/, { cases: { '$1==$S2' : { token: '@rematch', next: '@pop', nextEmbedded: '@pop' },
  778. '@default': '' } }],
  779. [/"/, 'string', '@string' ],
  780. [/&lt;/, '']
  781. ],</pre
  782. >
  783. <p>
  784. Only when we find a matching end tag (outside a string),
  785. <code>$1==$S2</code>, we pop the state and exit the embedded mode. Note that we need
  786. <a href="#@rematch"><code class="dt">@rematch</code></a> since the editor is ignoring
  787. our token classes until we actually exit the embedded mode (and we handle the close tag
  788. again in the <code>@root</code> state).
  789. </p>
  790. <p>&nbsp;</p>
  791. <h2 id="inspectingtokens">Inspecting Tokens</h2>
  792. <p>
  793. Monaco provides an <code>Inspect Tokens</code> tool in browsers to help identify the
  794. tokens parsed from source code.
  795. </p>
  796. <p>To activate:</p>
  797. <ol>
  798. <li>Press <kbd>F1</kbd> while focused on a Monaco instance</li>
  799. <li>Trigger the <code>Developer: Inspect Tokens</code> option</li>
  800. </ol>
  801. <p>
  802. This will show a display over the currently selected token for its language, token type,
  803. basic font style and colors, and selector you can target in your editor themes.
  804. </p>
  805. <p>&nbsp;</p>
  806. <h2>Additional Examples</h2>
  807. <p>
  808. Additional examples can be found in the
  809. <code class="dt">src/basic-languages</code> folder of the
  810. <a href="https://github.com/microsoft/monaco-editor">monaco-editor</a>
  811. repo.
  812. </p>
  813. </div>
  814. <!-- documentation -->
  815. </div>
  816. <!-- main -->
  817. <!--******************************************
  818. Samples are included as PRE elements
  819. **********************************************-->
  820. <div id="samples" style="display: none">
  821. <pre id="mylang-sample">
  822. // Type source code in your language here...
  823. class MyClass {
  824. @attribute
  825. void main() {
  826. Console.writeln( "Hello Monarch world\n");
  827. }
  828. }
  829. </pre
  830. >
  831. <pre id="mylang">
  832. // Create your own language definition here
  833. // You can safely look at other samples without losing modifications.
  834. // Modifications are not saved on browser refresh/close though -- copy often!
  835. return {
  836. // Set defaultToken to invalid to see what you do not tokenize yet
  837. // defaultToken: 'invalid',
  838. keywords: [
  839. 'abstract', 'continue', 'for', 'new', 'switch', 'assert', 'goto', 'do',
  840. 'if', 'private', 'this', 'break', 'protected', 'throw', 'else', 'public',
  841. 'enum', 'return', 'catch', 'try', 'interface', 'static', 'class',
  842. 'finally', 'const', 'super', 'while', 'true', 'false'
  843. ],
  844. typeKeywords: [
  845. 'boolean', 'double', 'byte', 'int', 'short', 'char', 'void', 'long', 'float'
  846. ],
  847. operators: [
  848. '=', '&gt;', '&lt;', '!', '~', '?', ':', '==', '&lt;=', '&gt;=', '!=',
  849. '&amp;&amp;', '||', '++', '--', '+', '-', '*', '/', '&amp;', '|', '^', '%',
  850. '&lt;&lt;', '&gt;&gt;', '&gt;&gt;&gt;', '+=', '-=', '*=', '/=', '&amp;=', '|=', '^=',
  851. '%=', '&lt;&lt;=', '&gt;&gt;=', '&gt;&gt;&gt;='
  852. ],
  853. // we include these common regular expressions
  854. symbols: /[=&gt;&lt;!~?:&amp;|+\-*\/\^%]+/,
  855. // C# style strings
  856. escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
  857. // The main tokenizer for our languages
  858. tokenizer: {
  859. root: [
  860. // identifiers and keywords
  861. [/[a-z_$][\w$]*/, { cases: { '@typeKeywords': 'keyword',
  862. '@keywords': 'keyword',
  863. '@default': 'identifier' } }],
  864. [/[A-Z][\w\$]*/, 'type.identifier' ], // to show class names nicely
  865. // whitespace
  866. { include: '@whitespace' },
  867. // delimiters and operators
  868. [/[{}()\[\]]/, '@brackets'],
  869. [/[&lt;&gt;](?!@symbols)/, '@brackets'],
  870. [/@symbols/, { cases: { '@operators': 'operator',
  871. '@default' : '' } } ],
  872. // @ annotations.
  873. // As an example, we emit a debugging log message on these tokens.
  874. // Note: message are supressed during the first load -- change some lines to see them.
  875. [/@\s*[a-zA-Z_\$][\w\$]*/, { token: 'annotation', log: 'annotation token: $0' }],
  876. // numbers
  877. [/\d*\.\d+([eE][\-+]?\d+)?/, 'number.float'],
  878. [/0[xX][0-9a-fA-F]+/, 'number.hex'],
  879. [/\d+/, 'number'],
  880. // delimiter: after number because of .\d floats
  881. [/[;,.]/, 'delimiter'],
  882. // strings
  883. [/"([^"\\]|\\.)*$/, 'string.invalid' ], // non-teminated string
  884. [/"/, { token: 'string.quote', bracket: '@open', next: '@string' } ],
  885. // characters
  886. [/'[^\\']'/, 'string'],
  887. [/(')(@escapes)(')/, ['string','string.escape','string']],
  888. [/'/, 'string.invalid']
  889. ],
  890. comment: [
  891. [/[^\/*]+/, 'comment' ],
  892. [/\/\*/, 'comment', '@push' ], // nested comment
  893. ["\\*/", 'comment', '@pop' ],
  894. [/[\/*]/, 'comment' ]
  895. ],
  896. string: [
  897. [/[^\\"]+/, 'string'],
  898. [/@escapes/, 'string.escape'],
  899. [/\\./, 'string.escape.invalid'],
  900. [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' } ]
  901. ],
  902. whitespace: [
  903. [/[ \t\r\n]+/, 'white'],
  904. [/\/\*/, 'comment', '@comment' ],
  905. [/\/\/.*$/, 'comment'],
  906. ],
  907. },
  908. };
  909. </pre
  910. >
  911. <pre id="java-sample">
  912. // Type source code in your Java here...
  913. public class HelloWorld {
  914. public static void main(String[] args) {
  915. System.out.println("Hello, World");
  916. }
  917. }
  918. </pre
  919. >
  920. <pre id="java">
  921. // Difficulty: "Easy"
  922. // Language definition for Java
  923. return {
  924. defaultToken: '',
  925. tokenPostfix: '.java',
  926. keywords: [
  927. 'abstract', 'continue', 'for', 'new', 'switch', 'assert', 'default',
  928. 'goto', 'package', 'synchronized', 'boolean', 'do', 'if', 'private',
  929. 'this', 'break', 'double', 'implements', 'protected', 'throw', 'byte',
  930. 'else', 'import', 'public', 'throws', 'case', 'enum', 'instanceof', 'return',
  931. 'transient', 'catch', 'extends', 'int', 'short', 'try', 'char', 'final',
  932. 'interface', 'static', 'void', 'class', 'finally', 'long', 'strictfp',
  933. 'volatile', 'const', 'float', 'native', 'super', 'while', 'true', 'false'
  934. ],
  935. operators: [
  936. '=', '&gt;', '&lt;', '!', '~', '?', ':',
  937. '==', '&lt;=', '&gt;=', '!=', '&amp;&amp;', '||', '++', '--',
  938. '+', '-', '*', '/', '&amp;', '|', '^', '%', '&lt;&lt;',
  939. '&gt;&gt;', '&gt;&gt;&gt;', '+=', '-=', '*=', '/=', '&amp;=', '|=',
  940. '^=', '%=', '&lt;&lt;=', '&gt;&gt;=', '&gt;&gt;&gt;='
  941. ],
  942. // we include these common regular expressions
  943. symbols: /[=&gt;&lt;!~?:&amp;|+\-*\/\^%]+/,
  944. escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
  945. digits: /\d+(_+\d+)*/,
  946. octaldigits: /[0-7]+(_+[0-7]+)*/,
  947. binarydigits: /[0-1]+(_+[0-1]+)*/,
  948. hexdigits: /[[0-9a-fA-F]+(_+[0-9a-fA-F]+)*/,
  949. // The main tokenizer for our languages
  950. tokenizer: {
  951. root: [
  952. // identifiers and keywords
  953. [/[a-zA-Z_$][\w$]*/, {
  954. cases: {
  955. '@keywords': { token: 'keyword.$0' },
  956. '@default': 'identifier'
  957. }
  958. }],
  959. // whitespace
  960. { include: '@whitespace' },
  961. // delimiters and operators
  962. [/[{}()\[\]]/, '@brackets'],
  963. [/[&lt;&gt;](?!@symbols)/, '@brackets'],
  964. [/@symbols/, {
  965. cases: {
  966. '@operators': 'delimiter',
  967. '@default': ''
  968. }
  969. }],
  970. // @ annotations.
  971. [/@\s*[a-zA-Z_\$][\w\$]*/, 'annotation'],
  972. // numbers
  973. [/(@digits)[eE]([\-+]?(@digits))?[fFdD]?/, 'number.float'],
  974. [/(@digits)\.(@digits)([eE][\-+]?(@digits))?[fFdD]?/, 'number.float'],
  975. [/0[xX](@hexdigits)[Ll]?/, 'number.hex'],
  976. [/0(@octaldigits)[Ll]?/, 'number.octal'],
  977. [/0[bB](@binarydigits)[Ll]?/, 'number.binary'],
  978. [/(@digits)[fFdD]/, 'number.float'],
  979. [/(@digits)[lL]?/, 'number'],
  980. // delimiter: after number because of .\d floats
  981. [/[;,.]/, 'delimiter'],
  982. // strings
  983. [/"([^"\\]|\\.)*$/, 'string.invalid'], // non-teminated string
  984. [/"/, 'string', '@string'],
  985. // characters
  986. [/'[^\\']'/, 'string'],
  987. [/(')(@escapes)(')/, ['string', 'string.escape', 'string']],
  988. [/'/, 'string.invalid']
  989. ],
  990. whitespace: [
  991. [/[ \t\r\n]+/, ''],
  992. [/\/\*\*(?!\/)/, 'comment.doc', '@javadoc'],
  993. [/\/\*/, 'comment', '@comment'],
  994. [/\/\/.*$/, 'comment'],
  995. ],
  996. comment: [
  997. [/[^\/*]+/, 'comment'],
  998. // [/\/\*/, 'comment', '@push' ], // nested comment not allowed :-(
  999. // [/\/\*/, 'comment.invalid' ], // this breaks block comments in the shape of /* //*/
  1000. [/\*\//, 'comment', '@pop'],
  1001. [/[\/*]/, 'comment']
  1002. ],
  1003. //Identical copy of comment above, except for the addition of .doc
  1004. javadoc: [
  1005. [/[^\/*]+/, 'comment.doc'],
  1006. // [/\/\*/, 'comment.doc', '@push' ], // nested comment not allowed :-(
  1007. [/\/\*/, 'comment.doc.invalid'],
  1008. [/\*\//, 'comment.doc', '@pop'],
  1009. [/[\/*]/, 'comment.doc']
  1010. ],
  1011. string: [
  1012. [/[^\\"]+/, 'string'],
  1013. [/@escapes/, 'string.escape'],
  1014. [/\\./, 'string.escape.invalid'],
  1015. [/"/, 'string', '@pop']
  1016. ],
  1017. },
  1018. };
  1019. </pre
  1020. >
  1021. <!--******************************************
  1022. Javascript
  1023. **********************************************-->
  1024. <pre id="javascript-sample">
  1025. // Type source code in JavaScript here...
  1026. define('module',[],function()
  1027. {
  1028. function test(s) {
  1029. return s.replace(/[a-z$]oo\noo$/, 'bar');
  1030. }
  1031. return {
  1032. main: alert(test("hello monarch world\n"))
  1033. }
  1034. });</pre
  1035. >
  1036. <pre id="javascript">
  1037. // Difficulty: "Moderate"
  1038. // This is the JavaScript tokenizer that is actually used to highlight
  1039. // all code in the syntax definition editor and the documentation!
  1040. //
  1041. // This definition takes special care to highlight regular
  1042. // expressions correctly, which is convenient when writing
  1043. // syntax highlighter specifications.
  1044. return {
  1045. // Set defaultToken to invalid to see what you do not tokenize yet
  1046. defaultToken: 'invalid',
  1047. tokenPostfix: '.js',
  1048. keywords: [
  1049. 'break', 'case', 'catch', 'class', 'continue', 'const',
  1050. 'constructor', 'debugger', 'default', 'delete', 'do', 'else',
  1051. 'export', 'extends', 'false', 'finally', 'for', 'from', 'function',
  1052. 'get', 'if', 'import', 'in', 'instanceof', 'let', 'new', 'null',
  1053. 'return', 'set', 'super', 'switch', 'symbol', 'this', 'throw', 'true',
  1054. 'try', 'typeof', 'undefined', 'var', 'void', 'while', 'with', 'yield',
  1055. 'async', 'await', 'of'
  1056. ],
  1057. typeKeywords: [
  1058. 'any', 'boolean', 'number', 'object', 'string', 'undefined'
  1059. ],
  1060. operators: [
  1061. '&lt;=', '&gt;=', '==', '!=', '===', '!==', '=&gt;', '+', '-', '**',
  1062. '*', '/', '%', '++', '--', '&lt;&lt;', '&lt;/', '&gt;&gt;', '&gt;&gt;&gt;', '&amp;',
  1063. '|', '^', '!', '~', '&amp;&amp;', '||', '?', ':', '=', '+=', '-=',
  1064. '*=', '**=', '/=', '%=', '&lt;&lt;=', '&gt;&gt;=', '&gt;&gt;&gt;=', '&amp;=', '|=',
  1065. '^=', '@',
  1066. ],
  1067. // we include these common regular expressions
  1068. symbols: /[=&gt;&lt;!~?:&amp;|+\-*\/\^%]+/,
  1069. escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
  1070. digits: /\d+(_+\d+)*/,
  1071. octaldigits: /[0-7]+(_+[0-7]+)*/,
  1072. binarydigits: /[0-1]+(_+[0-1]+)*/,
  1073. hexdigits: /[[0-9a-fA-F]+(_+[0-9a-fA-F]+)*/,
  1074. regexpctl: /[(){}\[\]\$\^|\-*+?\.]/,
  1075. regexpesc: /\\(?:[bBdDfnrstvwWn0\\\/]|@regexpctl|c[A-Z]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4})/,
  1076. // The main tokenizer for our languages
  1077. tokenizer: {
  1078. root: [
  1079. [/[{}]/, 'delimiter.bracket'],
  1080. { include: 'common' }
  1081. ],
  1082. common: [
  1083. // identifiers and keywords
  1084. [/[a-z_$][\w$]*/, {
  1085. cases: {
  1086. '@typeKeywords': 'keyword',
  1087. '@keywords': 'keyword',
  1088. '@default': 'identifier'
  1089. }
  1090. }],
  1091. [/[A-Z][\w\$]*/, 'type.identifier'], // to show class names nicely
  1092. // [/[A-Z][\w\$]*/, 'identifier'],
  1093. // whitespace
  1094. { include: '@whitespace' },
  1095. // regular expression: ensure it is terminated before beginning (otherwise it is an opeator)
  1096. [/\/(?=([^\\\/]|\\.)+\/([gimsuy]*)(\s*)(\.|;|\/|,|\)|\]|\}|$))/, { token: 'regexp', bracket: '@open', next: '@regexp' }],
  1097. // delimiters and operators
  1098. [/[()\[\]]/, '@brackets'],
  1099. [/[&lt;&gt;](?!@symbols)/, '@brackets'],
  1100. [/@symbols/, {
  1101. cases: {
  1102. '@operators': 'delimiter',
  1103. '@default': ''
  1104. }
  1105. }],
  1106. // numbers
  1107. [/(@digits)[eE]([\-+]?(@digits))?/, 'number.float'],
  1108. [/(@digits)\.(@digits)([eE][\-+]?(@digits))?/, 'number.float'],
  1109. [/0[xX](@hexdigits)/, 'number.hex'],
  1110. [/0[oO]?(@octaldigits)/, 'number.octal'],
  1111. [/0[bB](@binarydigits)/, 'number.binary'],
  1112. [/(@digits)/, 'number'],
  1113. // delimiter: after number because of .\d floats
  1114. [/[;,.]/, 'delimiter'],
  1115. // strings
  1116. [/"([^"\\]|\\.)*$/, 'string.invalid'], // non-teminated string
  1117. [/'([^'\\]|\\.)*$/, 'string.invalid'], // non-teminated string
  1118. [/"/, 'string', '@string_double'],
  1119. [/'/, 'string', '@string_single'],
  1120. [/`/, 'string', '@string_backtick'],
  1121. ],
  1122. whitespace: [
  1123. [/[ \t\r\n]+/, ''],
  1124. [/\/\*\*(?!\/)/, 'comment.doc', '@jsdoc'],
  1125. [/\/\*/, 'comment', '@comment'],
  1126. [/\/\/.*$/, 'comment'],
  1127. ],
  1128. comment: [
  1129. [/[^\/*]+/, 'comment'],
  1130. [/\*\//, 'comment', '@pop'],
  1131. [/[\/*]/, 'comment']
  1132. ],
  1133. jsdoc: [
  1134. [/[^\/*]+/, 'comment.doc'],
  1135. [/\*\//, 'comment.doc', '@pop'],
  1136. [/[\/*]/, 'comment.doc']
  1137. ],
  1138. // We match regular expression quite precisely
  1139. regexp: [
  1140. [/(\{)(\d+(?:,\d*)?)(\})/, ['regexp.escape.control', 'regexp.escape.control', 'regexp.escape.control']],
  1141. [/(\[)(\^?)(?=(?:[^\]\\\/]|\\.)+)/, ['regexp.escape.control', { token: 'regexp.escape.control', next: '@regexrange' }]],
  1142. [/(\()(\?:|\?=|\?!)/, ['regexp.escape.control', 'regexp.escape.control']],
  1143. [/[()]/, 'regexp.escape.control'],
  1144. [/@regexpctl/, 'regexp.escape.control'],
  1145. [/[^\\\/]/, 'regexp'],
  1146. [/@regexpesc/, 'regexp.escape'],
  1147. [/\\\./, 'regexp.invalid'],
  1148. [/(\/)([gimsuy]*)/, [{ token: 'regexp', bracket: '@close', next: '@pop' }, 'keyword.other']],
  1149. ],
  1150. regexrange: [
  1151. [/-/, 'regexp.escape.control'],
  1152. [/\^/, 'regexp.invalid'],
  1153. [/@regexpesc/, 'regexp.escape'],
  1154. [/[^\]]/, 'regexp'],
  1155. [/\]/, { token: 'regexp.escape.control', next: '@pop', bracket: '@close' }],
  1156. ],
  1157. string_double: [
  1158. [/[^\\"]+/, 'string'],
  1159. [/@escapes/, 'string.escape'],
  1160. [/\\./, 'string.escape.invalid'],
  1161. [/"/, 'string', '@pop']
  1162. ],
  1163. string_single: [
  1164. [/[^\\']+/, 'string'],
  1165. [/@escapes/, 'string.escape'],
  1166. [/\\./, 'string.escape.invalid'],
  1167. [/'/, 'string', '@pop']
  1168. ],
  1169. string_backtick: [
  1170. [/\$\{/, { token: 'delimiter.bracket', next: '@bracketCounting' }],
  1171. [/[^\\`$]+/, 'string'],
  1172. [/@escapes/, 'string.escape'],
  1173. [/\\./, 'string.escape.invalid'],
  1174. [/`/, 'string', '@pop']
  1175. ],
  1176. bracketCounting: [
  1177. [/\{/, 'delimiter.bracket', '@bracketCounting'],
  1178. [/\}/, 'delimiter.bracket', '@pop'],
  1179. { include: 'common' }
  1180. ],
  1181. },
  1182. };
  1183. </pre
  1184. >
  1185. <!--******************************************
  1186. Dafny
  1187. **********************************************-->
  1188. <pre id="dafny-sample">
  1189. // This method computes the sum and max of a given array of
  1190. // integers. The method's postcondition only promises that
  1191. // 'sum' will be no greater than 'max'. Can you write a
  1192. // different method body that also achieves this postcondition?
  1193. // Hint: Your program does not have to compute the sum and
  1194. // max of the array, despite the suggestive names of the
  1195. // out-parameters.
  1196. method M(N: int, a: array&lt;int&gt;) returns (sum: int, max: int)
  1197. requires 0 &lt;= N &amp; a != null &amp; a.Length == N;
  1198. ensures sum &lt;= N * max;
  1199. {
  1200. sum := 0;
  1201. max := 0;
  1202. var i := 0;
  1203. while (i &lt; N)
  1204. invariant i &lt;= N &amp; sum &lt;= i * max;
  1205. {
  1206. if (max &lt; a[i]) {
  1207. max := a[i];
  1208. }
  1209. sum := sum + a[i];
  1210. i := i + 1;
  1211. }
  1212. }
  1213. </pre
  1214. >
  1215. <pre id="dafny">
  1216. // Difficulty: "Easy"
  1217. // Language definition sample for the Dafny language.
  1218. // See 'http://rise4fun.com/Dafny'.
  1219. return {
  1220. keywords: [
  1221. 'class','datatype','codatatype','type','function',
  1222. 'ghost','var','method','constructor',
  1223. 'module','import','default','as','opened','static','refines',
  1224. 'returns','break','then','else','if','label','return','while','print','where',
  1225. 'new','parallel', 'in','this','fresh','choose',
  1226. 'match','case','assert','assume', 'predicate','copredicate',
  1227. 'forall','exists', 'false','true','null','old',
  1228. 'calc','iterator','yields','yield'
  1229. ],
  1230. verifyKeywords: [
  1231. 'requires','ensures','modifies','reads','free', 'invariant','decreases',
  1232. ],
  1233. types: [
  1234. 'bool','multiset','map','nat','int','object','set','seq', 'array'
  1235. ],
  1236. brackets: [
  1237. ['{','}','delimiter.curly'],
  1238. ['[',']','delimiter.square'],
  1239. ['(',')','delimiter.parenthesis']
  1240. ],
  1241. // Dafny uses C# style strings
  1242. escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
  1243. tokenizer: {
  1244. root: [
  1245. // identifiers
  1246. [/array([2-9]\d*|1\d+)/, 'type.keyword' ],
  1247. [/[a-zA-Z'_\?\\][\w'\?\\]*/, { cases: {'@keywords': 'keyword',
  1248. '@verifyKeywords': 'constructor.identifier',
  1249. '@types' : 'type.keyword',
  1250. '@default' : 'identifier' }}],
  1251. [':=','keyword'],
  1252. // whitespace
  1253. { include: '@whitespace' },
  1254. [/[{}()\[\]]/, '@brackets'],
  1255. [/[;,]/, 'delimiter'],
  1256. // literals
  1257. [/[0-9]+/, 'number'],
  1258. // strings
  1259. [/"([^"\\]|\\.)*$/, 'string.invalid' ], // non-teminated string
  1260. [/"/, 'string', '@string' ],
  1261. ],
  1262. whitespace: [
  1263. [/[ \t\r\n]+/, 'white'],
  1264. [/\/\*/, 'comment', '@comment' ],
  1265. [/\/\/.*$/, 'comment'],
  1266. ],
  1267. comment: [
  1268. [/[^\/*]+/, 'comment' ],
  1269. [/\/\*/, 'comment', '@push' ], // nested comment
  1270. ["\\*/", 'comment', '@pop' ],
  1271. [/[\/*]/, 'comment' ]
  1272. ],
  1273. string: [
  1274. [/[^\\"]+/, 'string'],
  1275. [/@escapes/, 'string.escape'],
  1276. [/\\./, 'string.escape.invalid'],
  1277. [/"/, 'string', '@pop' ]
  1278. ],
  1279. }
  1280. };</pre
  1281. >
  1282. <!--******************************************
  1283. Koka
  1284. **********************************************-->
  1285. <pre id="koka-sample">
  1286. // This module implements the Garcia-Wachs algorithm.
  1287. // It is an adaptation of the algorithm in ML as described by Jean-Christophe Filli�tre:
  1288. // in ''A functional implementation of the Garsia-Wachs algorithm. (functional pearl). ML workshop 2008, pages 91--96''.
  1289. // See: http://www.lri.fr/~filliatr/publis/gw-wml08.pdf
  1290. //
  1291. // The algorithm is interesting since it uses mutable references shared between a list and tree but the
  1292. // side-effects are not observable from outside. Koka automatically infers that final algorithm is pure.
  1293. module garcia-wachs
  1294. //----------------------------------------------------
  1295. // Trees
  1296. //----------------------------------------------------
  1297. public type tree&lt;a> {
  1298. con Leaf(value :a)
  1299. con Node(left :tree&lt;a>, right :tree&lt;a>)
  1300. }
  1301. fun show( t : tree&lt;char> ) : string
  1302. {
  1303. match(t) {
  1304. Leaf(c) -> Core.show(c)
  1305. Node(l,r) -> "Node(" + show(l) + "," + show(r) + ")"
  1306. }
  1307. }
  1308. //----------------------------------------------------
  1309. // Non empty lists
  1310. //----------------------------------------------------
  1311. public type list1&lt;a> {
  1312. Cons1( head : a, tail : list&lt;a> )
  1313. }
  1314. fun map( xs, f ) {
  1315. val Cons1(y,ys) = xs
  1316. return Cons1(f(y), Core.map(ys,f))
  1317. }
  1318. fun zip( xs :list1&lt;a>, ys :list1&lt;b> ) : list1&lt;(a,b)> {
  1319. Cons1( (xs.head, ys.head), Core.zip(xs.tail, ys.tail))
  1320. }
  1321. //----------------------------------------------------
  1322. // Phase 1
  1323. // note: koka cannot yet prove that the mutual recursive
  1324. // functions "insert" and "extract" always terminate :-(
  1325. //----------------------------------------------------
  1326. fun insert( after : list&lt;(tree&lt;a>,int)>, t : (tree&lt;a>,int), before : list&lt;(tree&lt;a>,int)> ) : div tree&lt;a>
  1327. {
  1328. match(before) {
  1329. Nil -> extract( [], Cons1(t,after) )
  1330. Cons(x,xs) -> {
  1331. if (x.snd &lt; t.snd) then return insert( Cons(x,after), t, xs )
  1332. match(xs) {
  1333. Nil -> extract( [], Cons1(x,Cons(t,after)) )
  1334. Cons(y,ys) -> extract( ys, Cons1(y,Cons(x,Cons(t,after))) )
  1335. }
  1336. }
  1337. }
  1338. }
  1339. fun extract( before : list&lt;(tree&lt;a>,int)>, after : list1&lt;(tree&lt;a>,int)> ) : div tree&lt;a>
  1340. {
  1341. val Cons1((t1,w1) as x, xs ) = after
  1342. match(xs) {
  1343. Nil -> t1
  1344. Cons((t2,w2) as y, ys) -> match(ys) {
  1345. Nil -> insert( [], (Node(t1,t2), w1+w2), before )
  1346. Cons((_,w3),_zs) ->
  1347. if (w1 &lt;= w3)
  1348. then insert(ys, (Node(t1,t2), w1+w2), before)
  1349. else extract(Cons(x,before), Cons1(y,ys))
  1350. }
  1351. }
  1352. }
  1353. fun balance( xs : list1&lt;(tree&lt;a>,int)> ) : div tree&lt;a>
  1354. {
  1355. extract( [], xs )
  1356. }
  1357. fun mark( depth :int, t :tree&lt;(a,ref&lt;h,int>)> ) : &lt;write&lt;h>> ()
  1358. {
  1359. match(t) {
  1360. Leaf((_,d)) -> d := depth
  1361. Node(l,r) -> { mark(depth+1,l); mark(depth+1,r) }
  1362. }
  1363. }
  1364. fun build( depth :int, xs :list1&lt;(a,ref&lt;h,int>)> ) : &lt;read&lt;h>,div> (tree&lt;a>,list&lt;(a,ref&lt;h,int>)>)
  1365. {
  1366. if (!xs.head.snd == depth) return (Leaf(xs.head.fst), xs.tail)
  1367. l = build(depth+1, xs)
  1368. match(l.snd) {
  1369. Nil -> (l.fst, Nil)
  1370. Cons(y,ys) -> {
  1371. r = build(depth+1, Cons1(y,ys))
  1372. (Node(l.fst,r.fst), r.snd)
  1373. }
  1374. }
  1375. }
  1376. public function garciawachs( xs : list1&lt;(a,int)> ) : div tree&lt;a>
  1377. {
  1378. refs = xs.map(fst).map( fun(x) { (x, ref(0)) } )
  1379. wleafs = zip( refs.map(Leaf), xs.map(snd) )
  1380. tree = balance(wleafs)
  1381. mark(0,tree)
  1382. build(0,refs).fst
  1383. }
  1384. public function main() {
  1385. wlist = Cons1(('a',3), [('b',2),('c',1),('d',4),('e',5)])
  1386. tree = wlist.garciawachs()
  1387. tree.show.print()
  1388. }
  1389. </pre
  1390. >
  1391. <pre id="koka">
  1392. // Difficulty: "Moderate"
  1393. // Language definition for the Koka language
  1394. // See 'rise4fun.com/Koka' for more information.
  1395. // This definition uses states extensively to color types correctly
  1396. // where it matches up brackets inside nested types.
  1397. return {
  1398. keywords: [
  1399. 'infix', 'infixr', 'infixl', 'prefix', 'postfix',
  1400. 'type', 'cotype', 'rectype', 'alias', 'struct', 'enum', 'con',
  1401. 'fun', 'function', 'val', 'var', 'external',
  1402. 'if', 'then', 'else', 'elif', 'return', 'match',
  1403. 'forall', 'exists', 'some', 'with',
  1404. 'private', 'public', 'private',
  1405. 'module', 'import', 'as',
  1406. '=', '.', ':', ':=', '-&gt;',
  1407. 'include', 'inline','rec','try', 'yield',
  1408. 'interface', 'instance'
  1409. ],
  1410. builtins: [
  1411. 'for', 'while', 'repeat',
  1412. 'foreach', 'foreach-indexed',
  1413. 'error', 'catch', 'finally',
  1414. 'cs', 'js', 'file', 'ref', 'assigned'
  1415. ],
  1416. typeKeywords: [
  1417. 'forall', 'exists', 'some', 'with'
  1418. ],
  1419. typeStart: [
  1420. 'type','cotype','rectype','alias','struct','enum'
  1421. ],
  1422. moduleKeywords: [
  1423. 'module','import','as'
  1424. ],
  1425. kindConstants: [
  1426. 'E','P','H','V','X'
  1427. ],
  1428. escapes : /\\(?:[nrt\\"'\?]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{6})/,
  1429. symbols0: /[\$%&amp;\*\+@!\/\\\^~=\.:\-\?]/,
  1430. symbols : /(?:@symbols0|[\|&lt;&gt;])+/,
  1431. idchars : /(?:\w|\-[a-zA-Z])*/,
  1432. tokenizer: {
  1433. root: [
  1434. // identifiers and operators
  1435. [/[a-z]@idchars/,
  1436. { cases:{ '@keywords': {
  1437. cases: { 'alias' : { token: 'keyword', next: '@alias_type' },
  1438. 'struct' : { token: 'keyword', next: '@struct_type' },
  1439. 'type|cotype|rectype': { token: 'keyword', next: '@type' },
  1440. 'module|as|import': { token: 'keyword', next: '@module' },
  1441. '@default': 'keyword' }
  1442. },
  1443. '@builtins': 'identifier.predefined',
  1444. '@default' : 'identifier' }
  1445. }
  1446. ],
  1447. [/([A-Z]@idchars)(\.?)/,
  1448. { cases: { '$2': ['identifier.namespace','keyword.dot'],
  1449. '@default': 'identifier.constructor' }}
  1450. ],
  1451. [/_@idchars/, 'identifier.wildcard'],
  1452. // whitespace
  1453. { include: '@whitespace' },
  1454. [/[{}()\[\]]/, '@brackets'],
  1455. [/[;,`]/, 'delimiter'],
  1456. // do not scan these as operators
  1457. [/[&lt;&gt;](?![&lt;&gt;|]*@symbols0)/, '@brackets' ],
  1458. [/-&gt;(?!@symbols0|[&gt;\|])/, 'keyword' ],
  1459. [/::?(?!@symbols0)/, 'type.operator', '@type'],
  1460. [/::?(?=\?)/, 'type.operator', '@type'],
  1461. // literal string
  1462. [/@"/, { token: 'string.quote', bracket: '@open', next: '@litstring' } ],
  1463. // operators
  1464. [/@symbols/, { cases: { '\\-': 'operator.minus',
  1465. '@keywords': 'keyword.operator',
  1466. '@default': 'operator' }}
  1467. ],
  1468. // numbers
  1469. [/[0-9]+\.[0-9]+([eE][\-+]?[0-9]+)?/, 'number.float'],
  1470. [/0[xX][0-9a-fA-F]+/, 'number.hex'],
  1471. [/[0-9]+/, 'number'],
  1472. // strings
  1473. [/"([^"\\]|\\.)*$/, 'string.invalid' ], // non-teminated string
  1474. [/"/, { token: 'string.quote', bracket: '@open', next: '@string' } ],
  1475. // characters
  1476. [/'[^\\']'/, 'string'],
  1477. [/(')(@escapes)(')/, ['string','string.escape','string']],
  1478. [/'/, 'string.invalid'],
  1479. // meta
  1480. [/^[ ]*#.*/, 'namespace']
  1481. ],
  1482. whitespace: [
  1483. [/[ \r\n]+/, 'white'],
  1484. ['/\\*', 'comment', '@comment' ],
  1485. ['//$', 'comment'],
  1486. ['//', 'comment', '@line_comment']
  1487. ],
  1488. comment: [
  1489. [/^\s*["|]\s*$/, 'comment', '@comment_docblock'],
  1490. [/[^\/*"|]+/, 'comment' ],
  1491. ['/\\*', 'comment', '@push' ],
  1492. ['\\*/', 'comment', '@pop' ],
  1493. [/(")((?:[^"]|"")*)(")/, ['comment','comment.doc','comment']],
  1494. [/(\|)((?:[^|]|\|\|)*)(\|)/, ['comment','comment.doc','comment']],
  1495. [/[\/*"|]/, 'comment']
  1496. ],
  1497. comment_docblock: [
  1498. [/\*\/|\/\*/, '@rematch', '@pop'], // recover: back to comment mode
  1499. [/^\s*"\s*$/, 'comment', '@pop'],
  1500. [/^\s*\|\s*$/, 'comment', '@pop'],
  1501. [/[^*\/]+/, 'comment.doc'],
  1502. [/./, 'comment.doc'] // catch all
  1503. ],
  1504. line_comment: [
  1505. [/[^"|]*$/, 'comment', '@pop' ],
  1506. [/[^"|]+/, 'comment' ],
  1507. [/(")((?:[^"]|"")*)(")/,
  1508. ['comment','comment.doc', { cases: { '@eos': { token: 'comment', next: '@pop' },
  1509. '@default': 'comment' }}]
  1510. ],
  1511. [/(\|)((?:[^|]|\|\|)*)(\|)/,
  1512. ['comment','comment.doc', { cases: { '@eos': { token: 'comment', next: '@pop' },
  1513. '@default': 'comment' }}]
  1514. ],
  1515. [/.*$/, 'comment', '@pop'] // catch all
  1516. ],
  1517. string: [
  1518. [/[^\\"]+/, 'string'],
  1519. [/@escapes/, 'string.escape'],
  1520. [/\\./, 'string.escape.invalid'],
  1521. [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' } ]
  1522. ],
  1523. litstring: [
  1524. [/[^"]+/, 'string'],
  1525. [/""/, 'string.escape'],
  1526. [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' } ]
  1527. ],
  1528. // Module mode: color names as module names
  1529. module: [
  1530. { include: '@whitespace' },
  1531. [/[a-z]@idchars/,
  1532. { cases: { '@moduleKeywords': 'keyword',
  1533. '@keywords': { token: '@rematch', next: '@pop' },
  1534. '@default': 'identifier.namespace' }}
  1535. ],
  1536. [/[A-Z]@idchars/, 'identifier.namespace'],
  1537. [/\.(?!@symbols)/, 'keyword.operator.dot'],
  1538. ['','','@pop'] // catch all
  1539. ],
  1540. // Koka type coloring is a bit involved but looks cool :-)
  1541. alias_type: [
  1542. ['=', 'keyword.operator'], // allow equal sign
  1543. { include: '@type' }
  1544. ],
  1545. struct_type: [
  1546. [ /\((?!,*\))/, '@brackets', '@pop'], // allow for tuple struct definition
  1547. { include: '@type' }
  1548. ],
  1549. type: [
  1550. [ /[(\[&lt;]/, { token: '@brackets.type' }, '@type_nested'],
  1551. { include: '@type_content' }
  1552. ],
  1553. type_nested: [
  1554. [/[)\]&gt;]/, { token: '@brackets.type' }, '@pop' ],
  1555. [/[(\[&lt;]/, { token: '@brackets.type' }, '@push'],
  1556. [/,/, 'delimiter.type'],
  1557. [/([a-z]@idchars)(\s*)(:)(?!:)/,['type.identifier.typeparam','white','type.operator']],
  1558. { include: '@type_content' }
  1559. ],
  1560. type_content: [
  1561. { include: '@whitespace' },
  1562. // type identifiers
  1563. [/[*!](?!@symbols)/, 'type.kind.identifier'],
  1564. [/[a-z][0-9]*(?![a-zA-Z_\-])/, 'type.identifier.typevar'],
  1565. [/_@idchars/, 'type.identifier.typevar'],
  1566. [/[a-z]@idchars/,
  1567. { cases: { '@typeKeywords': 'type.keyword',
  1568. '@keywords': { token: '@rematch', next: '@pop' },
  1569. '@builtins': 'type.predefined',
  1570. '@default': 'type.identifier'
  1571. }}
  1572. ],
  1573. [/[A-Z]@idchars(\.?)/,
  1574. { cases: { '$2': ['identifier.namespace','keyword.dot'],
  1575. '@kindConstants': 'type.kind.identifier',
  1576. '@default': 'type.identifier'
  1577. }}
  1578. ],
  1579. [/::|-&gt;|[\.:|]/, 'type.operator'],
  1580. ['','','@pop'] // catch all
  1581. ]
  1582. }
  1583. };
  1584. </pre
  1585. >
  1586. <!--******************************************
  1587. HTML
  1588. **********************************************-->
  1589. <pre id="html-sample">
  1590. &lt;!DOCTYPE html>
  1591. &lt;html>
  1592. &lt;head>
  1593. &lt;title>Monarch Workbench&lt;/title>
  1594. &lt;meta http-equiv="X-UA-Compatible" content="IE=edge" />
  1595. &lt;!-- a comment
  1596. -->
  1597. &lt;style>
  1598. body { font-family: Consolas; } /* nice */
  1599. &lt;/style>
  1600. &lt;/head>
  1601. &lt;body>
  1602. &lt;div class="test">
  1603. &lt;script>
  1604. function() {
  1605. alert("hi &lt;/script>"); // javascript
  1606. };
  1607. &lt;/script>
  1608. &lt;script type="text/x-dafny">
  1609. class Foo {
  1610. x : int;
  1611. invariant x > 0;
  1612. };
  1613. &lt;/script>
  1614. &lt;/div>
  1615. &lt;/body>
  1616. &lt;/html>
  1617. </pre
  1618. >
  1619. <pre id="html">
  1620. // Difficulty: "Hurt me plenty"
  1621. // Language definition for HTML
  1622. // This definition uses states extensively to
  1623. // - match up tags.
  1624. // - and to embed scripts dynamically
  1625. // See also the documentation for an explanation of these techniques
  1626. return {
  1627. defaultToken: '',
  1628. tokenPostfix: '.html',
  1629. ignoreCase: true,
  1630. // The main tokenizer for our languages
  1631. tokenizer: {
  1632. root: [
  1633. [/&lt;!DOCTYPE/, 'metatag', '@doctype'],
  1634. [/&lt;!--/, 'comment', '@comment'],
  1635. [/(&lt;)((?:[\w\-]+:)?[\w\-]+)(\s*)(\/&gt;)/, ['delimiter', 'tag', '', 'delimiter']],
  1636. [/(&lt;)(script)/, ['delimiter', { token: 'tag', next: '@script' }]],
  1637. [/(&lt;)(style)/, ['delimiter', { token: 'tag', next: '@style' }]],
  1638. [/(&lt;)((?:[\w\-]+:)?[\w\-]+)/, ['delimiter', { token: 'tag', next: '@otherTag' }]],
  1639. [/(&lt;\/)((?:[\w\-]+:)?[\w\-]+)/, ['delimiter', { token: 'tag', next: '@otherTag' }]],
  1640. [/&lt;/, 'delimiter'],
  1641. [/[^&lt;]+/], // text
  1642. ],
  1643. doctype: [
  1644. [/[^&gt;]+/, 'metatag.content'],
  1645. [/&gt;/, 'metatag', '@pop'],
  1646. ],
  1647. comment: [
  1648. [/--&gt;/, 'comment', '@pop'],
  1649. [/[^-]+/, 'comment.content'],
  1650. [/./, 'comment.content']
  1651. ],
  1652. otherTag: [
  1653. [/\/?&gt;/, 'delimiter', '@pop'],
  1654. [/"([^"]*)"/, 'attribute.value'],
  1655. [/'([^']*)'/, 'attribute.value'],
  1656. [/[\w\-]+/, 'attribute.name'],
  1657. [/=/, 'delimiter'],
  1658. [/[ \t\r\n]+/], // whitespace
  1659. ],
  1660. // -- BEGIN &lt;script&gt; tags handling
  1661. // After &lt;script
  1662. script: [
  1663. [/type/, 'attribute.name', '@scriptAfterType'],
  1664. [/"([^"]*)"/, 'attribute.value'],
  1665. [/'([^']*)'/, 'attribute.value'],
  1666. [/[\w\-]+/, 'attribute.name'],
  1667. [/=/, 'delimiter'],
  1668. [/&gt;/, { token: 'delimiter', next: '@scriptEmbedded', nextEmbedded: 'text/javascript' }],
  1669. [/[ \t\r\n]+/], // whitespace
  1670. [/(&lt;\/)(script\s*)(&gt;)/, ['delimiter', 'tag', { token: 'delimiter', next: '@pop' }]]
  1671. ],
  1672. // After &lt;script ... type
  1673. scriptAfterType: [
  1674. [/=/, 'delimiter', '@scriptAfterTypeEquals'],
  1675. [/&gt;/, { token: 'delimiter', next: '@scriptEmbedded', nextEmbedded: 'text/javascript' }], // cover invalid e.g. &lt;script type&gt;
  1676. [/[ \t\r\n]+/], // whitespace
  1677. [/&lt;\/script\s*&gt;/, { token: '@rematch', next: '@pop' }]
  1678. ],
  1679. // After &lt;script ... type =
  1680. scriptAfterTypeEquals: [
  1681. [/"([^"]*)"/, { token: 'attribute.value', switchTo: '@scriptWithCustomType.$1' }],
  1682. [/'([^']*)'/, { token: 'attribute.value', switchTo: '@scriptWithCustomType.$1' }],
  1683. [/&gt;/, { token: 'delimiter', next: '@scriptEmbedded', nextEmbedded: 'text/javascript' }], // cover invalid e.g. &lt;script type=&gt;
  1684. [/[ \t\r\n]+/], // whitespace
  1685. [/&lt;\/script\s*&gt;/, { token: '@rematch', next: '@pop' }]
  1686. ],
  1687. // After &lt;script ... type = $S2
  1688. scriptWithCustomType: [
  1689. [/&gt;/, { token: 'delimiter', next: '@scriptEmbedded.$S2', nextEmbedded: '$S2' }],
  1690. [/"([^"]*)"/, 'attribute.value'],
  1691. [/'([^']*)'/, 'attribute.value'],
  1692. [/[\w\-]+/, 'attribute.name'],
  1693. [/=/, 'delimiter'],
  1694. [/[ \t\r\n]+/], // whitespace
  1695. [/&lt;\/script\s*&gt;/, { token: '@rematch', next: '@pop' }]
  1696. ],
  1697. scriptEmbedded: [
  1698. [/&lt;\/script/, { token: '@rematch', next: '@pop', nextEmbedded: '@pop' }],
  1699. [/[^&lt;]+/, '']
  1700. ],
  1701. // -- END &lt;script&gt; tags handling
  1702. // -- BEGIN &lt;style&gt; tags handling
  1703. // After &lt;style
  1704. style: [
  1705. [/type/, 'attribute.name', '@styleAfterType'],
  1706. [/"([^"]*)"/, 'attribute.value'],
  1707. [/'([^']*)'/, 'attribute.value'],
  1708. [/[\w\-]+/, 'attribute.name'],
  1709. [/=/, 'delimiter'],
  1710. [/&gt;/, { token: 'delimiter', next: '@styleEmbedded', nextEmbedded: 'text/css' }],
  1711. [/[ \t\r\n]+/], // whitespace
  1712. [/(&lt;\/)(style\s*)(&gt;)/, ['delimiter', 'tag', { token: 'delimiter', next: '@pop' }]]
  1713. ],
  1714. // After &lt;style ... type
  1715. styleAfterType: [
  1716. [/=/, 'delimiter', '@styleAfterTypeEquals'],
  1717. [/&gt;/, { token: 'delimiter', next: '@styleEmbedded', nextEmbedded: 'text/css' }], // cover invalid e.g. &lt;style type&gt;
  1718. [/[ \t\r\n]+/], // whitespace
  1719. [/&lt;\/style\s*&gt;/, { token: '@rematch', next: '@pop' }]
  1720. ],
  1721. // After &lt;style ... type =
  1722. styleAfterTypeEquals: [
  1723. [/"([^"]*)"/, { token: 'attribute.value', switchTo: '@styleWithCustomType.$1' }],
  1724. [/'([^']*)'/, { token: 'attribute.value', switchTo: '@styleWithCustomType.$1' }],
  1725. [/&gt;/, { token: 'delimiter', next: '@styleEmbedded', nextEmbedded: 'text/css' }], // cover invalid e.g. &lt;style type=&gt;
  1726. [/[ \t\r\n]+/], // whitespace
  1727. [/&lt;\/style\s*&gt;/, { token: '@rematch', next: '@pop' }]
  1728. ],
  1729. // After &lt;style ... type = $S2
  1730. styleWithCustomType: [
  1731. [/&gt;/, { token: 'delimiter', next: '@styleEmbedded.$S2', nextEmbedded: '$S2' }],
  1732. [/"([^"]*)"/, 'attribute.value'],
  1733. [/'([^']*)'/, 'attribute.value'],
  1734. [/[\w\-]+/, 'attribute.name'],
  1735. [/=/, 'delimiter'],
  1736. [/[ \t\r\n]+/], // whitespace
  1737. [/&lt;\/style\s*&gt;/, { token: '@rematch', next: '@pop' }]
  1738. ],
  1739. styleEmbedded: [
  1740. [/&lt;\/style/, { token: '@rematch', next: '@pop', nextEmbedded: '@pop' }],
  1741. [/[^&lt;]+/, '']
  1742. ],
  1743. // -- END &lt;style&gt; tags handling
  1744. },
  1745. };
  1746. </pre
  1747. >
  1748. <!--******************************************
  1749. Markdown
  1750. **********************************************-->
  1751. <pre id="markdown-sample">
  1752. # Header 1 #
  1753. ## Header 2 ##
  1754. ### Header 3 ### (Hashes on right are optional)
  1755. ## Markdown plus h2 with a custom ID ## {#id-goes-here}
  1756. [Link back to H2](#id-goes-here)
  1757. &lt;!-- html madness -->
  1758. &lt;div class="custom-class" markdown="1">
  1759. &lt;div>
  1760. nested div
  1761. &lt;/div>
  1762. &lt;script type='text/x-koka'>
  1763. function( x: int ) { return x*x; }
  1764. &lt;/script>
  1765. This is a div _with_ underscores
  1766. and a &amp; &lt;b class="bold">bold&lt;/b> element.
  1767. &lt;style>
  1768. body { font: "Consolas" }
  1769. &lt;/style>
  1770. &lt;/div>
  1771. * Bullet lists are easy too
  1772. - Another one
  1773. + Another one
  1774. This is a paragraph, which is text surrounded by
  1775. whitespace. Paragraphs can be on one
  1776. line (or many), and can drone on for hours.
  1777. Now some inline markup like _italics_, **bold**,
  1778. and `code()`. Note that underscores
  1779. in_words_are ignored.
  1780. ````dafny
  1781. method Foo() {
  1782. requires "github style code blocks"
  1783. }
  1784. ````
  1785. ````application/json
  1786. { value: ["or with a mime type"] }
  1787. ````
  1788. > Blockquotes are like quoted text in email replies
  1789. >> And, they can be nested
  1790. 1. A numbered list
  1791. 2. Which is numbered
  1792. 3. With periods and a space
  1793. And now some code:
  1794. // Code is just text indented a bit
  1795. which(is_easy) to_remember();
  1796. And a block
  1797. ~~~
  1798. // Markdown extra adds un-indented code blocks too
  1799. if (this_is_more_code == true &amp;&amp; !indented) {
  1800. // tild wrapped code blocks, also not indented
  1801. }
  1802. ~~~
  1803. Text with
  1804. two trailing spaces
  1805. (on the right)
  1806. can be used
  1807. for things like poems
  1808. ### Horizontal rules
  1809. * * * *
  1810. ****
  1811. --------------------------
  1812. ![picture alt](/images/photo.jpeg "Title is optional")
  1813. ## Markdown plus tables ##
  1814. | Header | Header | Right |
  1815. | ------ | ------ | -----: |
  1816. | Cell | Cell | $10 |
  1817. | Cell | Cell | $20 |
  1818. * Outer pipes on tables are optional
  1819. * Colon used for alignment (right versus left)
  1820. ## Markdown plus definition lists ##
  1821. Bottled water
  1822. : $ 1.25
  1823. : $ 1.55 (Large)
  1824. Milk
  1825. Pop
  1826. : $ 1.75
  1827. * Multiple definitions and terms are possible
  1828. * Definitions can include multiple paragraphs too
  1829. *[ABBR]: Markdown plus abbreviations (produces an &lt;abbr> tag)
  1830. </pre
  1831. >
  1832. <pre id="markdown">
  1833. // Difficulty: "Ultra-Violence"
  1834. // Language definition for Markdown
  1835. // Quite complex definition mostly due to almost full inclusion
  1836. // of the HTML mode (so we can properly match nested HTML tag definitions)
  1837. return {
  1838. defaultToken: '',
  1839. tokenPostfix: '.md',
  1840. // escape codes
  1841. control: /[\\`*_\[\]{}()#+\-\.!]/,
  1842. noncontrol: /[^\\`*_\[\]{}()#+\-\.!]/,
  1843. escapes: /\\(?:@control)/,
  1844. // escape codes for javascript/CSS strings
  1845. jsescapes: /\\(?:[btnfr\\"']|[0-7][0-7]?|[0-3][0-7]{2})/,
  1846. // non matched elements
  1847. empty: [
  1848. 'area', 'base', 'basefont', 'br', 'col', 'frame',
  1849. 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param'
  1850. ],
  1851. tokenizer: {
  1852. root: [
  1853. // headers (with #)
  1854. [/^(\s{0,3})(#+)((?:[^\\#]|@escapes)+)((?:#+)?)/, ['white', 'keyword', 'keyword', 'keyword']],
  1855. // headers (with =)
  1856. [/^\s*(=+|\-+)\s*$/, 'keyword'],
  1857. // headers (with ***)
  1858. [/^\s*((\*[ ]?)+)\s*$/, 'meta.separator'],
  1859. // quote
  1860. [/^\s*&gt;+/, 'comment'],
  1861. // list (starting with * or number)
  1862. [/^\s*([\*\-+:]|\d+\.)\s/, 'keyword'],
  1863. // code block (4 spaces indent)
  1864. [/^(\t|[ ]{4})[^ ].*$/, 'string'],
  1865. // code block (3 tilde)
  1866. [/^\s*~~~\s*((?:\w|[\/\-#])+)?\s*$/, { token: 'string', next: '@codeblock' }],
  1867. // github style code blocks (with backticks and language)
  1868. [/^\s*```\s*((?:\w|[\/\-#])+)\s*$/, { token: 'string', next: '@codeblockgh', nextEmbedded: '$1' }],
  1869. // github style code blocks (with backticks but no language)
  1870. [/^\s*```\s*$/, { token: 'string', next: '@codeblock' }],
  1871. // markup within lines
  1872. { include: '@linecontent' },
  1873. ],
  1874. codeblock: [
  1875. [/^\s*~~~\s*$/, { token: 'string', next: '@pop' }],
  1876. [/^\s*```\s*$/, { token: 'string', next: '@pop' }],
  1877. [/.*$/, 'variable.source'],
  1878. ],
  1879. // github style code blocks
  1880. codeblockgh: [
  1881. [/```\s*$/, { token: 'variable.source', next: '@pop', nextEmbedded: '@pop' }],
  1882. [/[^`]+/, 'variable.source'],
  1883. ],
  1884. linecontent: [
  1885. // escapes
  1886. [/&amp;\w+;/, 'string.escape'],
  1887. [/@escapes/, 'escape'],
  1888. // various markup
  1889. [/\b__([^\\_]|@escapes|_(?!_))+__\b/, 'strong'],
  1890. [/\*\*([^\\*]|@escapes|\*(?!\*))+\*\*/, 'strong'],
  1891. [/\b_[^_]+_\b/, 'emphasis'],
  1892. [/\*([^\\*]|@escapes)+\*/, 'emphasis'],
  1893. [/`([^\\`]|@escapes)+`/, 'variable'],
  1894. // links
  1895. [/\{+[^}]+\}+/, 'string.target'],
  1896. [/(!?\[)((?:[^\]\\]|@escapes)*)(\]\([^\)]+\))/, ['string.link', '', 'string.link']],
  1897. [/(!?\[)((?:[^\]\\]|@escapes)*)(\])/, 'string.link'],
  1898. // or html
  1899. { include: 'html' },
  1900. ],
  1901. // Note: it is tempting to rather switch to the real HTML mode instead of building our own here
  1902. // but currently there is a limitation in Monarch that prevents us from doing it: The opening
  1903. // '&lt;' would start the HTML mode, however there is no way to jump 1 character back to let the
  1904. // HTML mode also tokenize the opening angle bracket. Thus, even though we could jump to HTML,
  1905. // we cannot correctly tokenize it in that mode yet.
  1906. html: [
  1907. // html tags
  1908. [/&lt;(\w+)\/&gt;/, 'tag'],
  1909. [/&lt;(\w+)/, {
  1910. cases: {
  1911. '@empty': { token: 'tag', next: '@tag.$1' },
  1912. '@default': { token: 'tag', next: '@tag.$1' }
  1913. }
  1914. }],
  1915. [/&lt;\/(\w+)\s*&gt;/, { token: 'tag' }],
  1916. [/&lt;!--/, 'comment', '@comment']
  1917. ],
  1918. comment: [
  1919. [/[^&lt;\-]+/, 'comment.content'],
  1920. [/--&gt;/, 'comment', '@pop'],
  1921. [/&lt;!--/, 'comment.content.invalid'],
  1922. [/[&lt;\-]/, 'comment.content']
  1923. ],
  1924. // Almost full HTML tag matching, complete with embedded scripts &amp; styles
  1925. tag: [
  1926. [/[ \t\r\n]+/, 'white'],
  1927. [/(type)(\s*=\s*)(")([^"]+)(")/, ['attribute.name.html', 'delimiter.html', 'string.html',
  1928. { token: 'string.html', switchTo: '@tag.$S2.$4' },
  1929. 'string.html']],
  1930. [/(type)(\s*=\s*)(')([^']+)(')/, ['attribute.name.html', 'delimiter.html', 'string.html',
  1931. { token: 'string.html', switchTo: '@tag.$S2.$4' },
  1932. 'string.html']],
  1933. [/(\w+)(\s*=\s*)("[^"]*"|'[^']*')/, ['attribute.name.html', 'delimiter.html', 'string.html']],
  1934. [/\w+/, 'attribute.name.html'],
  1935. [/\/&gt;/, 'tag', '@pop'],
  1936. [/&gt;/, {
  1937. cases: {
  1938. '$S2==style': { token: 'tag', switchTo: 'embeddedStyle', nextEmbedded: 'text/css' },
  1939. '$S2==script': {
  1940. cases: {
  1941. '$S3': { token: 'tag', switchTo: 'embeddedScript', nextEmbedded: '$S3' },
  1942. '@default': { token: 'tag', switchTo: 'embeddedScript', nextEmbedded: 'text/javascript' }
  1943. }
  1944. },
  1945. '@default': { token: 'tag', next: '@pop' }
  1946. }
  1947. }],
  1948. ],
  1949. embeddedStyle: [
  1950. [/[^&lt;]+/, ''],
  1951. [/&lt;\/style\s*&gt;/, { token: '@rematch', next: '@pop', nextEmbedded: '@pop' }],
  1952. [/&lt;/, '']
  1953. ],
  1954. embeddedScript: [
  1955. [/[^&lt;]+/, ''],
  1956. [/&lt;\/script\s*&gt;/, { token: '@rematch', next: '@pop', nextEmbedded: '@pop' }],
  1957. [/&lt;/, '']
  1958. ],
  1959. }
  1960. };
  1961. </pre
  1962. >
  1963. <pre id="ruby-sample">
  1964. #
  1965. # This program evaluates polynomials. It first asks for the coefficients
  1966. # of a polynomial, which must be entered on one line, highest-order first.
  1967. # It then requests values of x and will compute the value of the poly for
  1968. # each x. It will repeatly ask for x values, unless you the user enters
  1969. # a blank line. It that case, it will ask for another polynomial. If the
  1970. # user types quit for either input, the program immediately exits.
  1971. #
  1972. #
  1973. # Function to evaluate a polynomial at x. The polynomial is given
  1974. # as a list of coefficients, from the greatest to the least.
  1975. def polyval(x, coef)
  1976. sum = 0
  1977. coef = coef.clone # Don't want to destroy the original
  1978. while true
  1979. sum += coef.shift # Add and remove the next coef
  1980. break if coef.empty? # If no more, done entirely.
  1981. sum *= x # This happens the right number of times.
  1982. end
  1983. return sum
  1984. end
  1985. #
  1986. # Function to read a line containing a list of integers and return
  1987. # them as an array of integers. If the string conversion fails, it
  1988. # throws TypeError. If the input line is the word 'quit', then it
  1989. # converts it to an end-of-file exception
  1990. def readints(prompt)
  1991. # Read a line
  1992. print prompt
  1993. line = readline.chomp
  1994. raise EOFError.new if line == 'quit' # You can also use a real EOF.
  1995. # Go through each item on the line, converting each one and adding it
  1996. # to retval.
  1997. retval = [ ]
  1998. for str in line.split(/\s+/)
  1999. if str =~ /^\-?\d+$/
  2000. retval.push(str.to_i)
  2001. else
  2002. raise TypeError.new
  2003. end
  2004. end
  2005. return retval
  2006. end
  2007. #
  2008. # Take a coeff and an exponent and return the string representation, ignoring
  2009. # the sign of the coefficient.
  2010. def term_to_str(coef, exp)
  2011. ret = ""
  2012. # Show coeff, unless it's 1 or at the right
  2013. coef = coef.abs
  2014. ret = coef.to_s unless coef == 1 &amp;&amp; exp > 0
  2015. ret += "x" if exp > 0 # x if exponent not 0
  2016. ret += "^" + exp.to_s if exp > 1 # ^exponent, if > 1.
  2017. return ret
  2018. end
  2019. #
  2020. # Create a string of the polynomial in sort-of-readable form.
  2021. def polystr(p)
  2022. # Get the exponent of first coefficient, plus 1.
  2023. exp = p.length
  2024. # Assign exponents to each term, making pairs of coeff and exponent,
  2025. # Then get rid of the zero terms.
  2026. p = (p.map { |c| exp -= 1; [ c, exp ] }).select { |p| p[0] != 0 }
  2027. # If there's nothing left, it's a zero
  2028. return "0" if p.empty?
  2029. # *** Now p is a non-empty list of [ coef, exponent ] pairs. ***
  2030. # Convert the first term, preceded by a "-" if it's negative.
  2031. result = (if p[0][0] &lt; 0 then "-" else "" end) + term_to_str(*p[0])
  2032. # Convert the rest of the terms, in each case adding the appropriate
  2033. # + or - separating them.
  2034. for term in p[1...p.length]
  2035. # Add the separator then the rep. of the term.
  2036. result += (if term[0] &lt; 0 then " - " else " + " end) +
  2037. term_to_str(*term)
  2038. end
  2039. return result
  2040. end
  2041. #
  2042. # Run until some kind of endfile.
  2043. begin
  2044. # Repeat until an exception or quit gets us out.
  2045. while true
  2046. # Read a poly until it works. An EOF will except out of the
  2047. # program.
  2048. print "\n"
  2049. begin
  2050. poly = readints("Enter a polynomial coefficients: ")
  2051. rescue TypeError
  2052. print "Try again.\n"
  2053. retry
  2054. end
  2055. break if poly.empty?
  2056. # Read and evaluate x values until the user types a blank line.
  2057. # Again, an EOF will except out of the pgm.
  2058. while true
  2059. # Request an integer.
  2060. print "Enter x value or blank line: "
  2061. x = readline.chomp
  2062. break if x == ''
  2063. raise EOFError.new if x == 'quit'
  2064. # If it looks bad, let's try again.
  2065. if x !~ /^\-?\d+$/
  2066. print "That doesn't look like an integer. Please try again.\n"
  2067. next
  2068. end
  2069. # Convert to an integer and print the result.
  2070. x = x.to_i
  2071. print "p(x) = ", polystr(poly), "\n"
  2072. print "p(", x, ") = ", polyval(x, poly), "\n"
  2073. end
  2074. end
  2075. rescue EOFError
  2076. print "\n=== EOF ===\n"
  2077. rescue Interrupt, SignalException
  2078. print "\n=== Interrupted ===\n"
  2079. else
  2080. print "--- Bye ---\n"
  2081. end
  2082. </pre
  2083. >
  2084. <pre id="ruby">
  2085. // Difficulty: "Nightmare!"
  2086. /*
  2087. Ruby language definition
  2088. Quite a complex language due to elaborate escape sequences
  2089. and quoting of literate strings/regular expressions, and
  2090. an 'end' keyword that does not always apply to modifiers like until and while,
  2091. and a 'do' keyword that sometimes starts a block, but sometimes is part of
  2092. another statement (like 'while').
  2093. (1) end blocks:
  2094. 'end' may end declarations like if or until, but sometimes 'if' or 'until'
  2095. are modifiers where there is no 'end'. Also, 'do' sometimes starts a block
  2096. that is ended by 'end', but sometimes it is part of a 'while', 'for', or 'until'
  2097. To do proper brace matching we do some elaborate state manipulation.
  2098. some examples:
  2099. until bla do
  2100. work until tired
  2101. list.each do
  2102. foo if test
  2103. end
  2104. end
  2105. or
  2106. if test
  2107. foo (if test then x end)
  2108. bar if bla
  2109. end
  2110. or, how about using class as a property..
  2111. class Foo
  2112. def endpoint
  2113. self.class.endpoint || routes
  2114. end
  2115. end
  2116. (2) quoting:
  2117. there are many kinds of strings and escape sequences. But also, one can
  2118. start many string-like things as '%qx' where q specifies the kind of string
  2119. (like a command, escape expanded, regular expression, symbol etc.), and x is
  2120. some character and only another 'x' ends the sequence. Except for brackets
  2121. where the closing bracket ends the sequence.. and except for a nested bracket
  2122. inside the string like entity. Also, such strings can contain interpolated
  2123. ruby expressions again (and span multiple lines). Moreover, expanded
  2124. regular expression can also contain comments.
  2125. */
  2126. return {
  2127. tokenPostfix: '.ruby',
  2128. keywords: [
  2129. '__LINE__', '__ENCODING__', '__FILE__', 'BEGIN', 'END', 'alias', 'and', 'begin',
  2130. 'break', 'case', 'class', 'def', 'defined?', 'do', 'else', 'elsif', 'end',
  2131. 'ensure', 'for', 'false', 'if', 'in', 'module', 'next', 'nil', 'not', 'or', 'redo',
  2132. 'rescue', 'retry', 'return', 'self', 'super', 'then', 'true', 'undef', 'unless',
  2133. 'until', 'when', 'while', 'yield',
  2134. ],
  2135. keywordops: [
  2136. '::', '..', '...', '?', ':', '=&gt;'
  2137. ],
  2138. builtins: [
  2139. 'require', 'public', 'private', 'include', 'extend', 'attr_reader',
  2140. 'protected', 'private_class_method', 'protected_class_method', 'new'
  2141. ],
  2142. // these are closed by 'end' (if, while and until are handled separately)
  2143. declarations: [
  2144. 'module', 'class', 'def', 'case', 'do', 'begin', 'for', 'if', 'while', 'until', 'unless'
  2145. ],
  2146. linedecls: [
  2147. 'def', 'case', 'do', 'begin', 'for', 'if', 'while', 'until', 'unless'
  2148. ],
  2149. operators: [
  2150. '^', '&amp;', '|', '&lt;=&gt;', '==', '===', '!~', '=~', '&gt;', '&gt;=', '&lt;', '&lt;=', '&lt;&lt;', '&gt;&gt;', '+',
  2151. '-', '*', '/', '%', '**', '~', '+@', '-@', '[]', '[]=', '`',
  2152. '+=', '-=', '*=', '**=', '/=', '^=', '%=', '&lt;&lt;=', '&gt;&gt;=', '&amp;=', '&amp;&amp;=', '||=', '|='
  2153. ],
  2154. brackets: [
  2155. { open: '(', close: ')', token: 'delimiter.parenthesis' },
  2156. { open: '{', close: '}', token: 'delimiter.curly' },
  2157. { open: '[', close: ']', token: 'delimiter.square' }
  2158. ],
  2159. // we include these common regular expressions
  2160. symbols: /[=&gt;&lt;!~?:&amp;|+\-*\/\^%\.]+/,
  2161. // escape sequences
  2162. escape: /(?:[abefnrstv\\"'\n\r]|[0-7]{1,3}|x[0-9A-Fa-f]{1,2}|u[0-9A-Fa-f]{4})/,
  2163. escapes: /\\(?:C\-(@escape|.)|c(@escape|.)|@escape)/,
  2164. decpart: /\d(_?\d)*/,
  2165. decimal: /0|@decpart/,
  2166. delim: /[^a-zA-Z0-9\s\n\r]/,
  2167. heredelim: /(?:\w+|'[^']*'|"[^"]*"|`[^`]*`)/,
  2168. regexpctl: /[(){}\[\]\$\^|\-*+?\.]/,
  2169. regexpesc: /\\(?:[AzZbBdDfnrstvwWn0\\\/]|@regexpctl|c[A-Z]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4})?/,
  2170. // The main tokenizer for our languages
  2171. tokenizer: {
  2172. // Main entry.
  2173. // root.&lt;decl&gt; where decl is the current opening declaration (like 'class')
  2174. root: [
  2175. // identifiers and keywords
  2176. // most complexity here is due to matching 'end' correctly with declarations.
  2177. // We distinguish a declaration that comes first on a line, versus declarations further on a line (which are most likey modifiers)
  2178. [/^(\s*)([a-z_]\w*[!?=]?)/, ['white',
  2179. {
  2180. cases: {
  2181. 'for|until|while': { token: 'keyword.$2', next: '@dodecl.$2' },
  2182. '@declarations': { token: 'keyword.$2', next: '@root.$2' },
  2183. 'end': { token: 'keyword.$S2', next: '@pop' },
  2184. '@keywords': 'keyword',
  2185. '@builtins': 'predefined',
  2186. '@default': 'identifier'
  2187. }
  2188. }]],
  2189. [/[a-z_]\w*[!?=]?/,
  2190. {
  2191. cases: {
  2192. 'if|unless|while|until': { token: 'keyword.$0x', next: '@modifier.$0x' },
  2193. 'for': { token: 'keyword.$2', next: '@dodecl.$2' },
  2194. '@linedecls': { token: 'keyword.$0', next: '@root.$0' },
  2195. 'end': { token: 'keyword.$S2', next: '@pop' },
  2196. '@keywords': 'keyword',
  2197. '@builtins': 'predefined',
  2198. '@default': 'identifier'
  2199. }
  2200. }],
  2201. [/[A-Z][\w]*[!?=]?/, 'constructor.identifier'], // constant
  2202. [/\$[\w]*/, 'global.constant'], // global
  2203. [/@[\w]*/, 'namespace.instance.identifier'], // instance
  2204. [/@@[\w]*/, 'namespace.class.identifier'], // class
  2205. // here document
  2206. [/&lt;&lt;[-~](@heredelim).*/, { token: 'string.heredoc.delimiter', next: '@heredoc.$1' }],
  2207. [/[ \t\r\n]+&lt;&lt;(@heredelim).*/, { token: 'string.heredoc.delimiter', next: '@heredoc.$1' }],
  2208. [/^&lt;&lt;(@heredelim).*/, { token: 'string.heredoc.delimiter', next: '@heredoc.$1' }],
  2209. // whitespace
  2210. { include: '@whitespace' },
  2211. // strings
  2212. [/"/, { token: 'string.d.delim', next: '@dstring.d."' }],
  2213. [/'/, { token: 'string.sq.delim', next: '@sstring.sq' }],
  2214. // % literals. For efficiency, rematch in the 'pstring' state
  2215. [/%([rsqxwW]|Q?)/, { token: '@rematch', next: 'pstring' }],
  2216. // commands and symbols
  2217. [/`/, { token: 'string.x.delim', next: '@dstring.x.`' }],
  2218. [/:(\w|[$@])\w*[!?=]?/, 'string.s'],
  2219. [/:"/, { token: 'string.s.delim', next: '@dstring.s."' }],
  2220. [/:'/, { token: 'string.s.delim', next: '@sstring.s' }],
  2221. // regular expressions. Lookahead for a (not escaped) closing forwardslash on the same line
  2222. [/\/(?=(\\\/|[^\/\n])+\/)/, { token: 'regexp.delim', next: '@regexp' }],
  2223. // delimiters and operators
  2224. [/[{}()\[\]]/, '@brackets'],
  2225. [/@symbols/, {
  2226. cases: {
  2227. '@keywordops': 'keyword',
  2228. '@operators': 'operator',
  2229. '@default': ''
  2230. }
  2231. }],
  2232. [/[;,]/, 'delimiter'],
  2233. // numbers
  2234. [/0[xX][0-9a-fA-F](_?[0-9a-fA-F])*/, 'number.hex'],
  2235. [/0[_oO][0-7](_?[0-7])*/, 'number.octal'],
  2236. [/0[bB][01](_?[01])*/, 'number.binary'],
  2237. [/0[dD]@decpart/, 'number'],
  2238. [/@decimal((\.@decpart)?([eE][\-+]?@decpart)?)/, {
  2239. cases: {
  2240. '$1': 'number.float',
  2241. '@default': 'number'
  2242. }
  2243. }],
  2244. ],
  2245. // used to not treat a 'do' as a block opener if it occurs on the same
  2246. // line as a 'do' statement: 'while|until|for'
  2247. // dodecl.&lt;decl&gt; where decl is the declarations started, like 'while'
  2248. dodecl: [
  2249. [/^/, { token: '', switchTo: '@root.$S2' }], // get out of do-skipping mode on a new line
  2250. [/[a-z_]\w*[!?=]?/, {
  2251. cases: {
  2252. 'end': { token: 'keyword.$S2', next: '@pop' }, // end on same line
  2253. 'do': { token: 'keyword', switchTo: '@root.$S2' }, // do on same line: not an open bracket here
  2254. '@linedecls': { token: '@rematch', switchTo: '@root.$S2' }, // other declaration on same line: rematch
  2255. '@keywords': 'keyword',
  2256. '@builtins': 'predefined',
  2257. '@default': 'identifier'
  2258. }
  2259. }],
  2260. { include: '@root' }
  2261. ],
  2262. // used to prevent potential modifiers ('if|until|while|unless') to match
  2263. // with 'end' keywords.
  2264. // modifier.&lt;decl&gt;x where decl is the declaration starter, like 'if'
  2265. modifier: [
  2266. [/^/, '', '@pop'], // it was a modifier: get out of modifier mode on a new line
  2267. [/[a-z_]\w*[!?=]?/, {
  2268. cases: {
  2269. 'end': { token: 'keyword.$S2', next: '@pop' }, // end on same line
  2270. 'then|else|elsif|do': { token: 'keyword', switchTo: '@root.$S2' }, // real declaration and not a modifier
  2271. '@linedecls': { token: '@rematch', switchTo: '@root.$S2' }, // other declaration =&gt; not a modifier
  2272. '@keywords': 'keyword',
  2273. '@builtins': 'predefined',
  2274. '@default': 'identifier'
  2275. }
  2276. }],
  2277. { include: '@root' }
  2278. ],
  2279. // single quote strings (also used for symbols)
  2280. // sstring.&lt;kind&gt; where kind is 'sq' (single quote) or 's' (symbol)
  2281. sstring: [
  2282. [/[^\\']+/, 'string.$S2'],
  2283. [/\\\\|\\'|\\$/, 'string.$S2.escape'],
  2284. [/\\./, 'string.$S2.invalid'],
  2285. [/'/, { token: 'string.$S2.delim', next: '@pop' }]
  2286. ],
  2287. // double quoted "string".
  2288. // dstring.&lt;kind&gt;.&lt;delim&gt; where kind is 'd' (double quoted), 'x' (command), or 's' (symbol)
  2289. // and delim is the ending delimiter (" or `)
  2290. dstring: [
  2291. [/[^\\`"#]+/, 'string.$S2'],
  2292. [/#/, 'string.$S2.escape', '@interpolated'],
  2293. [/\\$/, 'string.$S2.escape'],
  2294. [/@escapes/, 'string.$S2.escape'],
  2295. [/\\./, 'string.$S2.escape.invalid'],
  2296. [/[`"]/, {
  2297. cases: {
  2298. '$#==$S3': { token: 'string.$S2.delim', next: '@pop' },
  2299. '@default': 'string.$S2'
  2300. }
  2301. }]
  2302. ],
  2303. // literal documents
  2304. // heredoc.&lt;close&gt; where close is the closing delimiter
  2305. heredoc: [
  2306. [/^(\s*)(@heredelim)$/, {
  2307. cases: {
  2308. '$2==$S2': ['string.heredoc', { token: 'string.heredoc.delimiter', next: '@pop' }],
  2309. '@default': ['string.heredoc', 'string.heredoc']
  2310. }
  2311. }],
  2312. [/.*/, 'string.heredoc'],
  2313. ],
  2314. // interpolated sequence
  2315. interpolated: [
  2316. [/\$\w*/, 'global.constant', '@pop'],
  2317. [/@\w*/, 'namespace.class.identifier', '@pop'],
  2318. [/@@\w*/, 'namespace.instance.identifier', '@pop'],
  2319. [/[{]/, { token: 'string.escape.curly', switchTo: '@interpolated_compound' }],
  2320. ['', '', '@pop'], // just a # is interpreted as a #
  2321. ],
  2322. // any code
  2323. interpolated_compound: [
  2324. [/[}]/, { token: 'string.escape.curly', next: '@pop' }],
  2325. { include: '@root' },
  2326. ],
  2327. // %r quoted regexp
  2328. // pregexp.&lt;open&gt;.&lt;close&gt; where open/close are the open/close delimiter
  2329. pregexp: [
  2330. { include: '@whitespace' },
  2331. // turns out that you can quote using regex control characters, aargh!
  2332. // for example; %r|kgjgaj| is ok (even though | is used for alternation)
  2333. // so, we need to match those first
  2334. [/[^\(\{\[\\]/, {
  2335. cases: {
  2336. '$#==$S3': { token: 'regexp.delim', next: '@pop' },
  2337. '$#==$S2': { token: 'regexp.delim', next: '@push' }, // nested delimiters are allowed..
  2338. '~[)}\\]]': '@brackets.regexp.escape.control',
  2339. '~@regexpctl': 'regexp.escape.control',
  2340. '@default': 'regexp'
  2341. }
  2342. }],
  2343. { include: '@regexcontrol' },
  2344. ],
  2345. // We match regular expression quite precisely
  2346. regexp: [
  2347. { include: '@regexcontrol' },
  2348. [/[^\\\/]/, 'regexp'],
  2349. ['/[ixmp]*', { token: 'regexp.delim' }, '@pop'],
  2350. ],
  2351. regexcontrol: [
  2352. [/(\{)(\d+(?:,\d*)?)(\})/, ['@brackets.regexp.escape.control', 'regexp.escape.control', '@brackets.regexp.escape.control']],
  2353. [/(\[)(\^?)/, ['@brackets.regexp.escape.control', { token: 'regexp.escape.control', next: '@regexrange' }]],
  2354. [/(\()(\?[:=!])/, ['@brackets.regexp.escape.control', 'regexp.escape.control']],
  2355. [/\(\?#/, { token: 'regexp.escape.control', next: '@regexpcomment' }],
  2356. [/[()]/, '@brackets.regexp.escape.control'],
  2357. [/@regexpctl/, 'regexp.escape.control'],
  2358. [/\\$/, 'regexp.escape'],
  2359. [/@regexpesc/, 'regexp.escape'],
  2360. [/\\\./, 'regexp.invalid'],
  2361. [/#/, 'regexp.escape', '@interpolated'],
  2362. ],
  2363. regexrange: [
  2364. [/-/, 'regexp.escape.control'],
  2365. [/\^/, 'regexp.invalid'],
  2366. [/\\$/, 'regexp.escape'],
  2367. [/@regexpesc/, 'regexp.escape'],
  2368. [/[^\]]/, 'regexp'],
  2369. [/\]/, '@brackets.regexp.escape.control', '@pop'],
  2370. ],
  2371. regexpcomment: [
  2372. [/[^)]+/, 'comment'],
  2373. [/\)/, { token: 'regexp.escape.control', next: '@pop' }]
  2374. ],
  2375. // % quoted strings
  2376. // A bit repetitive since we need to often special case the kind of ending delimiter
  2377. pstring: [
  2378. [/%([qws])\(/, { token: 'string.$1.delim', switchTo: '@qstring.$1.(.)' }],
  2379. [/%([qws])\[/, { token: 'string.$1.delim', switchTo: '@qstring.$1.[.]' }],
  2380. [/%([qws])\{/, { token: 'string.$1.delim', switchTo: '@qstring.$1.{.}' }],
  2381. [/%([qws])&lt;/, { token: 'string.$1.delim', switchTo: '@qstring.$1.&lt;.&gt;' }],
  2382. [/%([qws])(@delim)/, { token: 'string.$1.delim', switchTo: '@qstring.$1.$2.$2' }],
  2383. [/%r\(/, { token: 'regexp.delim', switchTo: '@pregexp.(.)' }],
  2384. [/%r\[/, { token: 'regexp.delim', switchTo: '@pregexp.[.]' }],
  2385. [/%r\{/, { token: 'regexp.delim', switchTo: '@pregexp.{.}' }],
  2386. [/%r&lt;/, { token: 'regexp.delim', switchTo: '@pregexp.&lt;.&gt;' }],
  2387. [/%r(@delim)/, { token: 'regexp.delim', switchTo: '@pregexp.$1.$1' }],
  2388. [/%(x|W|Q?)\(/, { token: 'string.$1.delim', switchTo: '@qqstring.$1.(.)' }],
  2389. [/%(x|W|Q?)\[/, { token: 'string.$1.delim', switchTo: '@qqstring.$1.[.]' }],
  2390. [/%(x|W|Q?)\{/, { token: 'string.$1.delim', switchTo: '@qqstring.$1.{.}' }],
  2391. [/%(x|W|Q?)&lt;/, { token: 'string.$1.delim', switchTo: '@qqstring.$1.&lt;.&gt;' }],
  2392. [/%(x|W|Q?)(@delim)/, { token: 'string.$1.delim', switchTo: '@qqstring.$1.$2.$2' }],
  2393. [/%([rqwsxW]|Q?)./, { token: 'invalid', next: '@pop' }], // recover
  2394. [/./, { token: 'invalid', next: '@pop' }], // recover
  2395. ],
  2396. // non-expanded quoted string.
  2397. // qstring.&lt;kind&gt;.&lt;open&gt;.&lt;close&gt;
  2398. // kind = q|w|s (single quote, array, symbol)
  2399. // open = open delimiter
  2400. // close = close delimiter
  2401. qstring: [
  2402. [/\\$/, 'string.$S2.escape'],
  2403. [/\\./, 'string.$S2.escape'],
  2404. [/./, {
  2405. cases: {
  2406. '$#==$S4': { token: 'string.$S2.delim', next: '@pop' },
  2407. '$#==$S3': { token: 'string.$S2.delim', next: '@push' }, // nested delimiters are allowed..
  2408. '@default': 'string.$S2'
  2409. }
  2410. }],
  2411. ],
  2412. // expanded quoted string.
  2413. // qqstring.&lt;kind&gt;.&lt;open&gt;.&lt;close&gt;
  2414. // kind = Q|W|x (double quote, array, command)
  2415. // open = open delimiter
  2416. // close = close delimiter
  2417. qqstring: [
  2418. [/#/, 'string.$S2.escape', '@interpolated'],
  2419. { include: '@qstring' }
  2420. ],
  2421. // whitespace &amp; comments
  2422. whitespace: [
  2423. [/[ \t\r\n]+/, ''],
  2424. [/^\s*=begin\b/, 'comment', '@comment'],
  2425. [/#.*$/, 'comment'],
  2426. ],
  2427. comment: [
  2428. [/[^=]+/, 'comment'],
  2429. [/^\s*=begin\b/, 'comment.invalid'], // nested comment
  2430. [/^\s*=end\b.*/, 'comment', '@pop'],
  2431. [/[=]/, 'comment']
  2432. ],
  2433. }
  2434. };
  2435. </pre
  2436. >
  2437. <pre id="python-sample">
  2438. from Tkinter import *
  2439. import Pmw, string
  2440. class SLabel(Frame):
  2441. """ SLabel defines a 2-sided label within a Frame. The
  2442. left hand label has blue letters the right has white letters """
  2443. def __init__(self, master, leftl, rightl):
  2444. Frame.__init__(self, master, bg='gray40')
  2445. self.pack(side=LEFT, expand=YES, fill=BOTH)
  2446. Label(self, text=leftl, fg='steelblue1',
  2447. font=("arial", 6, "bold"), width=5, bg='gray40').pack(
  2448. side=LEFT, expand=YES, fill=BOTH)
  2449. Label(self, text=rightl, fg='white',
  2450. font=("arial", 6, "bold"), width=1, bg='gray40').pack(
  2451. side=RIGHT, expand=YES, fill=BOTH)
  2452. class Key(Button):
  2453. def __init__(self, master, font=('arial', 8, 'bold'),
  2454. fg='white',width=5, borderwidth=5, **kw):
  2455. kw['font'] = font
  2456. kw['fg'] = fg
  2457. kw['width'] = width
  2458. kw['borderwidth'] = borderwidth
  2459. apply(Button.__init__, (self, master), kw)
  2460. self.pack(side=LEFT, expand=NO, fill=NONE)
  2461. class Calculator(Frame):
  2462. def __init__(self, parent=None):
  2463. Frame.__init__(self, bg='gray40')
  2464. self.pack(expand=YES, fill=BOTH)
  2465. self.master.title('Tkinter Toolkit TT-42')
  2466. self.master.iconname('Tk-42')
  2467. self.calc = Evaluator() # This is our evaluator
  2468. self.buildCalculator() # Build the widgets
  2469. # This is an incomplete dictionary - a good exercise!
  2470. self.actionDict = {'second': self.doThis, 'mode': self.doThis,
  2471. 'delete': self.doThis, 'alpha': self.doThis,
  2472. 'stat': self.doThis, 'math': self.doThis,
  2473. 'matrix': self.doThis, 'program': self.doThis,
  2474. 'vars': self.doThis, 'clear': self.clearall,
  2475. 'sin': self.doThis, 'cos': self.doThis,
  2476. 'tan': self.doThis, 'up': self.doThis,
  2477. 'X1': self.doThis, 'X2': self.doThis,
  2478. 'log': self.doThis, 'ln': self.doThis,
  2479. 'store': self.doThis, 'off': self.turnoff,
  2480. 'neg': self.doThis, 'enter': self.doEnter,
  2481. }
  2482. self.current = ""
  2483. def doThis(self,action):
  2484. print '"%s" has not been implemented' % action
  2485. def turnoff(self, *args):
  2486. self.quit()
  2487. def clearall(self, *args):
  2488. self.current = ""
  2489. self.display.component('text').delete(1.0, END)
  2490. def doEnter(self, *args):
  2491. result = self.calc.runpython(self.current)
  2492. if result:
  2493. self.display.insert(END, '\n')
  2494. self.display.insert(END, '%s\n' % result, 'ans')
  2495. self.current = ""
  2496. def doKeypress(self, event):
  2497. key = event.char
  2498. if not key in ['\b']:
  2499. self.current = self.current + event.char
  2500. if key == '\b':
  2501. self.current = self.current[:-1]
  2502. def keyAction(self, key):
  2503. self.display.insert(END, key)
  2504. self.current = self.current + key
  2505. def evalAction(self, action):
  2506. try:
  2507. self.actionDict[action](action)
  2508. except KeyError:
  2509. pass
  2510. def buildCalculator(self):
  2511. FUN = 1 # Designates a Function
  2512. KEY = 0 # Designates a Key
  2513. KC1 = 'gray30' # Dark Keys
  2514. KC2 = 'gray50' # Light Keys
  2515. KC3 = 'steelblue1' # Light Blue Key
  2516. KC4 = 'steelblue' # Dark Blue Key
  2517. keys = [
  2518. [('2nd', '', '', KC3, FUN, 'second'), # Row 1
  2519. ('Mode', 'Quit', '', KC1, FUN, 'mode'),
  2520. ('Del', 'Ins', '', KC1, FUN, 'delete'),
  2521. ('Alpha','Lock', '', KC2, FUN, 'alpha'),
  2522. ('Stat', 'List', '', KC1, FUN, 'stat')],
  2523. [('Math', 'Test', 'A', KC1, FUN, 'math'), # Row 2
  2524. ('Mtrx', 'Angle','B', KC1, FUN, 'matrix'),
  2525. ('Prgm', 'Draw', 'C', KC1, FUN, 'program'),
  2526. ('Vars', 'YVars','', KC1, FUN, 'vars'),
  2527. ('Clr', '', '', KC1, FUN, 'clear')],
  2528. [('X-1', 'Abs', 'D', KC1, FUN, 'X1'), # Row 3
  2529. ('Sin', 'Sin-1','E', KC1, FUN, 'sin'),
  2530. ('Cos', 'Cos-1','F', KC1, FUN, 'cos'),
  2531. ('Tan', 'Tan-1','G', KC1, FUN, 'tan'),
  2532. ('^', 'PI', 'H', KC1, FUN, 'up')],
  2533. [('X2', 'Root', 'I', KC1, FUN, 'X2'), # Row 4
  2534. (',', 'EE', 'J', KC1, KEY, ','),
  2535. ('(', '{', 'K', KC1, KEY, '('),
  2536. (')', '}', 'L', KC1, KEY, ')'),
  2537. ('/', '', 'M', KC4, KEY, '/')],
  2538. [('Log', '10x', 'N', KC1, FUN, 'log'), # Row 5
  2539. ('7', 'Un-1', 'O', KC2, KEY, '7'),
  2540. ('8', 'Vn-1', 'P', KC2, KEY, '8'),
  2541. ('9', 'n', 'Q', KC2, KEY, '9'),
  2542. ('X', '[', 'R', KC4, KEY, '*')],
  2543. [('Ln', 'ex', 'S', KC1, FUN, 'ln'), # Row 6
  2544. ('4', 'L4', 'T', KC2, KEY, '4'),
  2545. ('5', 'L5', 'U', KC2, KEY, '5'),
  2546. ('6', 'L6', 'V', KC2, KEY, '6'),
  2547. ('-', ']', 'W', KC4, KEY, '-')],
  2548. [('STO', 'RCL', 'X', KC1, FUN, 'store'), # Row 7
  2549. ('1', 'L1', 'Y', KC2, KEY, '1'),
  2550. ('2', 'L2', 'Z', KC2, KEY, '2'),
  2551. ('3', 'L3', '', KC2, KEY, '3'),
  2552. ('+', 'MEM', '"', KC4, KEY, '+')],
  2553. [('Off', '', '', KC1, FUN, 'off'), # Row 8
  2554. ('0', '', '', KC2, KEY, '0'),
  2555. ('.', ':', '', KC2, KEY, '.'),
  2556. ('(-)', 'ANS', '?', KC2, FUN, 'neg'),
  2557. ('Enter','Entry','', KC4, FUN, 'enter')]]
  2558. self.display = Pmw.ScrolledText(self, hscrollmode='dynamic',
  2559. vscrollmode='dynamic', hull_relief='sunken',
  2560. hull_background='gray40', hull_borderwidth=10,
  2561. text_background='honeydew4', text_width=16,
  2562. text_foreground='black', text_height=6,
  2563. text_padx=10, text_pady=10, text_relief='groove',
  2564. text_font=('arial', 12, 'bold'))
  2565. self.display.pack(side=TOP, expand=YES, fill=BOTH)
  2566. self.display.tag_config('ans', foreground='white')
  2567. self.display.component('text').bind('&lt;Key>', self.doKeypress)
  2568. self.display.component('text').bind('&lt;Return>', self.doEnter)
  2569. for row in keys:
  2570. rowa = Frame(self, bg='gray40')
  2571. rowb = Frame(self, bg='gray40')
  2572. for p1, p2, p3, color, ktype, func in row:
  2573. if ktype == FUN:
  2574. a = lambda s=self, a=func: s.evalAction(a)
  2575. else:
  2576. a = lambda s=self, k=func: s.keyAction(k)
  2577. SLabel(rowa, p2, p3)
  2578. Key(rowb, text=p1, bg=color, command=a)
  2579. rowa.pack(side=TOP, expand=YES, fill=BOTH)
  2580. rowb.pack(side=TOP, expand=YES, fill=BOTH)
  2581. class Evaluator:
  2582. def __init__(self):
  2583. self.myNameSpace = {}
  2584. self.runpython("from math import *")
  2585. def runpython(self, code):
  2586. try:
  2587. return 'eval(code, self.myNameSpace, self.myNameSpace)'
  2588. except SyntaxError:
  2589. try:
  2590. exec code in self.myNameSpace, self.myNameSpace
  2591. except:
  2592. return 'Error'
  2593. Calculator().mainloop()
  2594. </pre
  2595. >
  2596. <pre id="python">
  2597. // Difficulty: "Moderate"
  2598. // Python language definition.
  2599. // Only trickiness is that we need to check strings before identifiers
  2600. // since they have letter prefixes. We also treat ':' as an @open bracket
  2601. // in order to get auto identation.
  2602. return {
  2603. defaultToken: '',
  2604. tokenPostfix: '.python',
  2605. keywords: [
  2606. 'and',
  2607. 'as',
  2608. 'assert',
  2609. 'break',
  2610. 'class',
  2611. 'continue',
  2612. 'def',
  2613. 'del',
  2614. 'elif',
  2615. 'else',
  2616. 'except',
  2617. 'exec',
  2618. 'finally',
  2619. 'for',
  2620. 'from',
  2621. 'global',
  2622. 'if',
  2623. 'import',
  2624. 'in',
  2625. 'is',
  2626. 'lambda',
  2627. 'None',
  2628. 'not',
  2629. 'or',
  2630. 'pass',
  2631. 'print',
  2632. 'raise',
  2633. 'return',
  2634. 'self',
  2635. 'try',
  2636. 'while',
  2637. 'with',
  2638. 'yield',
  2639. 'int',
  2640. 'float',
  2641. 'long',
  2642. 'complex',
  2643. 'hex',
  2644. 'abs',
  2645. 'all',
  2646. 'any',
  2647. 'apply',
  2648. 'basestring',
  2649. 'bin',
  2650. 'bool',
  2651. 'buffer',
  2652. 'bytearray',
  2653. 'callable',
  2654. 'chr',
  2655. 'classmethod',
  2656. 'cmp',
  2657. 'coerce',
  2658. 'compile',
  2659. 'complex',
  2660. 'delattr',
  2661. 'dict',
  2662. 'dir',
  2663. 'divmod',
  2664. 'enumerate',
  2665. 'eval',
  2666. 'execfile',
  2667. 'file',
  2668. 'filter',
  2669. 'format',
  2670. 'frozenset',
  2671. 'getattr',
  2672. 'globals',
  2673. 'hasattr',
  2674. 'hash',
  2675. 'help',
  2676. 'id',
  2677. 'input',
  2678. 'intern',
  2679. 'isinstance',
  2680. 'issubclass',
  2681. 'iter',
  2682. 'len',
  2683. 'locals',
  2684. 'list',
  2685. 'map',
  2686. 'max',
  2687. 'memoryview',
  2688. 'min',
  2689. 'next',
  2690. 'object',
  2691. 'oct',
  2692. 'open',
  2693. 'ord',
  2694. 'pow',
  2695. 'print',
  2696. 'property',
  2697. 'reversed',
  2698. 'range',
  2699. 'raw_input',
  2700. 'reduce',
  2701. 'reload',
  2702. 'repr',
  2703. 'reversed',
  2704. 'round',
  2705. 'set',
  2706. 'setattr',
  2707. 'slice',
  2708. 'sorted',
  2709. 'staticmethod',
  2710. 'str',
  2711. 'sum',
  2712. 'super',
  2713. 'tuple',
  2714. 'type',
  2715. 'unichr',
  2716. 'unicode',
  2717. 'vars',
  2718. 'xrange',
  2719. 'zip',
  2720. 'True',
  2721. 'False',
  2722. '__dict__',
  2723. '__methods__',
  2724. '__members__',
  2725. '__class__',
  2726. '__bases__',
  2727. '__name__',
  2728. '__mro__',
  2729. '__subclasses__',
  2730. '__init__',
  2731. '__import__'
  2732. ],
  2733. brackets: [
  2734. { open: '{', close: '}', token: 'delimiter.curly' },
  2735. { open: '[', close: ']', token: 'delimiter.bracket' },
  2736. { open: '(', close: ')', token: 'delimiter.parenthesis' }
  2737. ],
  2738. tokenizer: {
  2739. root: [
  2740. { include: '@whitespace' },
  2741. { include: '@numbers' },
  2742. { include: '@strings' },
  2743. [/[,:;]/, 'delimiter'],
  2744. [/[{}\[\]()]/, '@brackets'],
  2745. [/@[a-zA-Z]\w*/, 'tag'],
  2746. [/[a-zA-Z]\w*/, {
  2747. cases: {
  2748. '@keywords': 'keyword',
  2749. '@default': 'identifier'
  2750. }
  2751. }]
  2752. ],
  2753. // Deal with white space, including single and multi-line comments
  2754. whitespace: [
  2755. [/\s+/, 'white'],
  2756. [/(^#.*$)/, 'comment'],
  2757. [/('''.*''')|(""".*""")/, 'string'],
  2758. [/'''.*$/, 'string', '@endDocString'],
  2759. [/""".*$/, 'string', '@endDblDocString']
  2760. ],
  2761. endDocString: [
  2762. [/\\'/, 'string'],
  2763. [/.*'''/, 'string', '@popall'],
  2764. [/.*$/, 'string']
  2765. ],
  2766. endDblDocString: [
  2767. [/\\"/, 'string'],
  2768. [/.*"""/, 'string', '@popall'],
  2769. [/.*$/, 'string']
  2770. ],
  2771. // Recognize hex, negatives, decimals, imaginaries, longs, and scientific notation
  2772. numbers: [
  2773. [/-?0x([abcdef]|[ABCDEF]|\d)+[lL]?/, 'number.hex'],
  2774. [/-?(\d*\.)?\d+([eE][+\-]?\d+)?[jJ]?[lL]?/, 'number']
  2775. ],
  2776. // Recognize strings, including those broken across lines with \ (but not without)
  2777. strings: [
  2778. [/'$/, 'string.escape', '@popall'],
  2779. [/'/, 'string.escape', '@stringBody'],
  2780. [/"$/, 'string.escape', '@popall'],
  2781. [/"/, 'string.escape', '@dblStringBody']
  2782. ],
  2783. stringBody: [
  2784. [/[^\\']+$/, 'string', '@popall'],
  2785. [/[^\\']+/, 'string'],
  2786. [/\\./, 'string'],
  2787. [/'/, 'string.escape', '@popall'],
  2788. [/\\$/, 'string']
  2789. ],
  2790. dblStringBody: [
  2791. [/[^\\"]+$/, 'string', '@popall'],
  2792. [/[^\\"]+/, 'string'],
  2793. [/\\./, 'string'],
  2794. [/"/, 'string.escape', '@popall'],
  2795. [/\\$/, 'string']
  2796. ]
  2797. }
  2798. };
  2799. </pre
  2800. >
  2801. <pre id="z3python-sample">
  2802. # 9x9 matrix of integer variables
  2803. X = [ [ Int("x_%s_%s" % (i+1, j+1)) for j in range(9) ]
  2804. for i in range(9) ]
  2805. # each cell contains a value in {1, ..., 9}
  2806. cells_c = [ And(1 &lt;= X[i][j], X[i][j] &lt;= 9)
  2807. for i in range(9) for j in range(9) ]
  2808. # each row contains a digit at most once
  2809. rows_c = [ Distinct(X[i]) for i in range(9) ]
  2810. # each column contains a digit at most once
  2811. cols_c = [ Distinct([ X[i][j] for i in range(9) ])
  2812. for j in range(9) ]
  2813. # each 3x3 square contains a digit at most once
  2814. sq_c = [ Distinct([ X[3*i0 + i][3*j0 + j]
  2815. for i in range(3) for j in range(3) ])
  2816. for i0 in range(3) for j0 in range(3) ]
  2817. sudoku_c = cells_c + rows_c + cols_c + sq_c
  2818. # sudoku instance, we use '0' for empty cells
  2819. instance = ((0,0,0,0,9,4,0,3,0),
  2820. (0,0,0,5,1,0,0,0,7),
  2821. (0,8,9,0,0,0,0,4,0),
  2822. (0,0,0,0,0,0,2,0,8),
  2823. (0,6,0,2,0,1,0,5,0),
  2824. (1,0,2,0,0,0,0,0,0),
  2825. (0,7,0,0,0,0,5,2,0),
  2826. (9,0,0,0,6,5,0,0,0),
  2827. (0,4,0,9,7,0,0,0,0))
  2828. instance_c = [ If(instance[i][j] == 0,
  2829. True,
  2830. X[i][j] == instance[i][j])
  2831. for i in range(9) for j in range(9) ]
  2832. s = Solver()
  2833. s.add(sudoku_c + instance_c)
  2834. if s.check() == sat:
  2835. m = s.model()
  2836. r = [ [ m.evaluate(X[i][j]) for j in range(9) ]
  2837. for i in range(9) ]
  2838. print_matrix(r)
  2839. else:
  2840. print "failed to solve"
  2841. </pre
  2842. >
  2843. <pre id="z3python">
  2844. // Difficulty: "Moderate"
  2845. // This is the Python language definition but specialized for use with Z3
  2846. // See also: http://www.rise4fun.com/Z3Py
  2847. return {
  2848. // Set defaultToken to invalid to see what you do not tokenize yet
  2849. // defaultToken: 'invalid',
  2850. keywords: [
  2851. 'and', 'del', 'from', 'not', 'while',
  2852. 'as', 'elif', 'global', 'or', 'with',
  2853. 'assert', 'else', 'if', 'pass', 'yield',
  2854. 'break', 'except', 'import', 'print',
  2855. 'class', 'exec', 'in', 'raise', 'continue', 'finally', 'is',
  2856. 'return', 'def', 'for', 'lambda', 'try',
  2857. ':','=',
  2858. 'isinstance','__debug__',
  2859. ],
  2860. operators: [
  2861. '+', '-', '*', '**', '/', '//', '%',
  2862. '&lt;&lt;', '&gt;&gt;', '&amp;', '|', '^', '~',
  2863. '&lt;', '&gt;', '&lt;=', '&gt;=', '==', '!=', '&lt;&gt;',
  2864. '+=', '-=', '*=', '/=', '//=', '%=',
  2865. '&amp;=', '|=', '^=', '&gt;&gt;=', '&lt;&lt;=', '**=',
  2866. ],
  2867. builtins: [
  2868. 'set_option', 'solve', 'simplify', 'Int', 'Real', 'Bool', 'open_log',
  2869. 'append_log', 'is_sort', 'DeclareSort', 'Function', 'is_func_decl', 'is_expr',
  2870. 'is_app', 'is_const', 'is_var', 'get_var_index', 'is_app_of',
  2871. 'If', 'Distinct', 'Const', 'Consts', 'Var', 'is_bool',
  2872. 'is_true', 'is_false', 'is_and', 'is_or', 'is_not', 'is_eq',
  2873. 'BoolSort', 'BoolVal', 'Bools', 'BoolVector', 'FreshBool',
  2874. 'Implies', 'Not', 'And', 'Or', 'MultiPattern', 'ForAll',
  2875. 'Exists', 'is_int', 'is_real', 'is_int_value', 'is_rational_value',
  2876. 'is_algebraic_value', 'IntSort', 'RealSort', 'IntVal',
  2877. 'RealVal', 'RatVal', 'Q', 'Ints', 'Reals', 'IntVector', 'RealVector',
  2878. 'FreshInt', 'FreshReal', 'ToReal', 'ToInt', 'IsInt',
  2879. 'Sqrt', 'Cbrt', 'is_bv', 'BV2Int', 'BitVecSort', 'BitVecVal',
  2880. 'BitVec', 'BitVecs', 'Concat', 'Extract', 'ULE', 'ULT',
  2881. 'UGE', 'UGT', 'UDiv', 'URem', 'SRem', 'LShR', 'RotateLeft',
  2882. 'RotateRight', 'SignExt', 'ZeroExt', 'RepeatBitVec',
  2883. 'is_array', 'ArraySort', 'Array', 'Update', 'Store',
  2884. 'Select', 'Map', 'K', 'CreateDatatypes', 'EnumSort', 'Solver',
  2885. 'SolverFor', 'SimpleSolver', 'FixedPoint', 'Tactic', 'AndThen',
  2886. 'Then', 'OrElse', 'ParOr', 'ParThen', 'ParAndThen',
  2887. 'With', 'Repeat', 'TryFor', 'Probe', 'When', 'FailIf', 'Cond',
  2888. 'substitute', 'Sum', 'Product', 'solve_using', 'prove', 'init', 'sat', 'unsat',
  2889. 'unknown'
  2890. ],
  2891. brackets: [
  2892. ['(',')','delimiter.parenthesis'],
  2893. ['{','}','delimiter.curly'],
  2894. ['[',']','delimiter.square']
  2895. ],
  2896. // operator symbols
  2897. symbols: /[=&gt;&lt;!~&amp;|+\-*\/\^%]+/,
  2898. delimiters: /[;=.@:,`]/,
  2899. // strings
  2900. escapes: /\\(?:[abfnrtv\\"'\n\r]|x[0-9A-Fa-f]{2}|[0-7]{3}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8}|N\{\w+\})/,
  2901. rawpre: /(?:[rR]|ur|Ur|uR|UR|br|Br|bR|BR)/,
  2902. strpre: /(?:[buBU])/,
  2903. // The main tokenizer for our languages
  2904. tokenizer: {
  2905. root: [
  2906. // strings: need to check first due to the prefix
  2907. [/@strpre?("""|''')/, { token: 'string.delim', bracket: '@open', next: '@mstring.$1' } ],
  2908. [/@strpre?"([^"\\]|\\.)*$/, 'string.invalid' ], // non-teminated string
  2909. [/@strpre?'([^'\\]|\\.)*$/, 'string.invalid' ], // non-teminated string
  2910. [/@strpre?(["'])/, { token: 'string.delim', bracket: '@open', next: '@string.$1' } ],
  2911. [/@rawpre("""|''')/, { token: 'string.delim', bracket: '@open', next: '@mrawstring.$1' } ],
  2912. [/@rawpre"([^"\\]|\\.)*$/, 'string.invalid' ], // non-teminated string
  2913. [/@rawpre'([^'\\]|\\.)*$/, 'string.invalid' ], // non-teminated string
  2914. [/@rawpre(["'])/, { token: 'string.delim', bracket: '@open', next: '@rawstring.$1' } ],
  2915. // identifiers and keywords
  2916. [/__[\w$]*/, 'predefined' ],
  2917. [/[a-z_$][\w$]*/, { cases: { '@keywords': 'keyword',
  2918. '@builtins': 'constructor.identifier',
  2919. '@default': 'identifier' } }],
  2920. [/[A-Z][\w]*/, { cases: { '~[A-Z0-9_]+': 'constructor.identifier',
  2921. '@builtins' : 'constructor.identifier',
  2922. '@default' : 'namespace.identifier' }}], // to show class names nicely
  2923. // whitespace
  2924. { include: '@whitespace' },
  2925. // delimiters and operators
  2926. [/[{}()\[\]]/, '@brackets'],
  2927. [/@symbols/, { cases: { '@keywords' : 'keyword',
  2928. '@operators': 'operator',
  2929. '@default' : '' } } ],
  2930. // numbers
  2931. [/\d*\.\d+([eE][\-+]?\d+)?/, 'number.float'],
  2932. [/0[xX][0-9a-fA-F]+[lL]?/, 'number.hex'],
  2933. [/0[bB][0-1]+[lL]?/, 'number.binary'],
  2934. [/(0[oO][0-7]+|0[0-7]+)[lL]?/, 'number.octal'],
  2935. [/(0|[1-9]\d*)[lL]?/, 'number'],
  2936. // delimiter: after number because of .\d floats
  2937. [':', { token: 'keyword', bracket: '@open' }], // bracket for indentation
  2938. [/@delimiters/, { cases: { '@keywords': 'keyword',
  2939. '@default': 'delimiter' }}],
  2940. ],
  2941. comment: [
  2942. [/[^\/*]+/, 'comment' ],
  2943. [/\/\*/, 'comment', '@push' ], // nested comment
  2944. ["\\*/", 'comment', '@pop' ],
  2945. [/[\/*]/, 'comment' ]
  2946. ],
  2947. // Regular strings
  2948. mstring: [
  2949. { include: '@strcontent' },
  2950. [/"""|'''/, { cases: { '$#==$S2': { token: 'string.delim', bracket: '@close', next: '@pop' },
  2951. '@default': { token: 'string' } } }],
  2952. [/["']/, 'string' ],
  2953. [/./, 'string.invalid'],
  2954. ],
  2955. string: [
  2956. { include: '@strcontent' },
  2957. [/["']/, { cases: { '$#==$S2': { token: 'string.delim', bracket: '@close', next: '@pop' },
  2958. '@default': { token: 'string' } } } ],
  2959. [/./, 'string.invalid'],
  2960. ],
  2961. strcontent: [
  2962. [/[^\\"']+/, 'string'],
  2963. [/\\$/, 'string.escape'],
  2964. [/@escapes/, 'string.escape'],
  2965. [/\\./, 'string.escape.invalid'],
  2966. ],
  2967. // Raw strings: we distinguish them to color escape sequences correctly
  2968. mrawstring: [
  2969. { include: '@rawstrcontent' },
  2970. [/"""|'''/, { cases: { '$#==$S2': { token: 'string.delim', bracket: '@close', next: '@pop' },
  2971. '@default': { token: 'string' } } }],
  2972. [/["']/, 'string' ],
  2973. [/./, 'string.invalid'],
  2974. ],
  2975. rawstring: [
  2976. { include: '@rawstrcontent' },
  2977. [/["']/, { cases: { '$#==$S2': { token: 'string.delim', bracket: '@close', next: '@pop' },
  2978. '@default': { token: 'string' } } } ],
  2979. [/./, 'string.invalid'],
  2980. ],
  2981. rawstrcontent: [
  2982. [/[^\\"']+/, 'string'],
  2983. [/\\["']/, 'string'],
  2984. [/\\u[0-9A-Fa-f]{4}/, 'string.escape'],
  2985. [/\\/, 'string' ],
  2986. ],
  2987. // whitespace
  2988. whitespace: [
  2989. [/[ \t\r\n]+/, 'white'],
  2990. [/#.*$/, 'comment'],
  2991. ],
  2992. },
  2993. };
  2994. </pre
  2995. >
  2996. <pre id="smt2-sample">
  2997. ; This example illustrates different uses of the arrays
  2998. ; supported in Z3.
  2999. ; This includes Combinatory Array Logic (de Moura &amp; Bjorner, FMCAD 2009).
  3000. ;
  3001. (define-sort A () (Array Int Int))
  3002. (declare-fun x () Int)
  3003. (declare-fun y () Int)
  3004. (declare-fun z () Int)
  3005. (declare-fun a1 () A)
  3006. (declare-fun a2 () A)
  3007. (declare-fun a3 () A)
  3008. (push) ; illustrate select-store
  3009. (assert (= (select a1 x) x))
  3010. (assert (= (store a1 x y) a1))
  3011. (check-sat)
  3012. (get-model)
  3013. (assert (not (= x y)))
  3014. (check-sat)
  3015. (pop)
  3016. (define-fun all1_array () A ((as const A) 1))
  3017. (simplify (select all1_array x))
  3018. (define-sort IntSet () (Array Int Bool))
  3019. (declare-fun a () IntSet)
  3020. (declare-fun b () IntSet)
  3021. (declare-fun c () IntSet)
  3022. (push) ; illustrate map
  3023. (assert (not (= ((_ map and) a b) ((_ map not) ((_ map or) ((_ map not) b) ((_ map not) a))))))
  3024. (check-sat)
  3025. (pop)
  3026. (push)
  3027. (assert (and (select ((_ map and) a b) x) (not (select a x))))
  3028. (check-sat)
  3029. (pop)
  3030. (push)
  3031. (assert (and (select ((_ map or) a b) x) (not (select a x))))
  3032. (check-sat)
  3033. (get-model)
  3034. (assert (and (not (select b x))))
  3035. (check-sat)
  3036. ;; unsat, so there is no model.
  3037. (pop)
  3038. (push) ; illustrate default
  3039. (assert (= (default a1) 1))
  3040. (assert (not (= a1 ((as const A) 1))))
  3041. (check-sat)
  3042. (get-model)
  3043. (assert (= (default a2) 1))
  3044. (assert (not (= a1 a2)))
  3045. (check-sat)
  3046. (get-model)
  3047. (pop)
  3048. (exit)
  3049. </pre
  3050. >
  3051. <pre id="smt2">
  3052. // Difficulty: "Easy"
  3053. // SMT 2.0 language
  3054. // See http://www.rise4fun.com/z3 or http://www.smtlib.org/ for more information
  3055. return {
  3056. // Set defaultToken to invalid to see what you do not tokenize yet
  3057. // defaultToken: 'invalid',
  3058. keywords: [
  3059. 'define-fun', 'define-const', 'assert', 'push', 'pop', 'assert', 'check-sat',
  3060. 'declare-const', 'declare-fun', 'get-model', 'get-value', 'declare-sort',
  3061. 'declare-datatypes', 'reset', 'eval', 'set-logic', 'help', 'get-assignment',
  3062. 'exit', 'get-proof', 'get-unsat-core', 'echo', 'let', 'forall', 'exists',
  3063. 'define-sort', 'set-option', 'get-option', 'set-info', 'check-sat-using', 'apply', 'simplify',
  3064. 'display', 'as', '!', 'get-info', 'declare-map', 'declare-rel', 'declare-var', 'rule',
  3065. 'query', 'get-user-tactics'
  3066. ],
  3067. operators: [
  3068. '=', '&gt;', '&lt;', '&lt;=', '&gt;=', '=&gt;', '+', '-', '*', '/',
  3069. ],
  3070. builtins: [
  3071. 'mod', 'div', 'rem', '^', 'to_real', 'and', 'or', 'not', 'distinct',
  3072. 'to_int', 'is_int', '~', 'xor', 'if', 'ite', 'true', 'false', 'root-obj',
  3073. 'sat', 'unsat', 'const', 'map', 'store', 'select', 'sat', 'unsat',
  3074. 'bit1', 'bit0', 'bvneg', 'bvadd', 'bvsub', 'bvmul', 'bvsdiv', 'bvudiv', 'bvsrem',
  3075. 'bvurem', 'bvsmod', 'bvule', 'bvsle', 'bvuge', 'bvsge', 'bvult',
  3076. 'bvslt', 'bvugt', 'bvsgt', 'bvand', 'bvor', 'bvnot', 'bvxor', 'bvnand',
  3077. 'bvnor', 'bvxnor', 'concat', 'sign_extend', 'zero_extend', 'extract',
  3078. 'repeat', 'bvredor', 'bvredand', 'bvcomp', 'bvshl', 'bvlshr', 'bvashr',
  3079. 'rotate_left', 'rotate_right', 'get-assertions'
  3080. ],
  3081. brackets: [
  3082. ['(',')','delimiter.parenthesis'],
  3083. ['{','}','delimiter.curly'],
  3084. ['[',']','delimiter.square']
  3085. ],
  3086. // we include these common regular expressions
  3087. symbols: /[=&gt;&lt;~&amp;|+\-*\/%@#]+/,
  3088. // C# style strings
  3089. escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
  3090. // The main tokenizer for our languages
  3091. tokenizer: {
  3092. root: [
  3093. // identifiers and keywords
  3094. [/[a-z_][\w\-\.']*/, { cases: { '@builtins': 'predefined.identifier',
  3095. '@keywords': 'keyword',
  3096. '@default': 'identifier' } }],
  3097. [/[A-Z][\w\-\.']*/, 'type.identifier' ],
  3098. [/[:][\w\-\.']*/, 'string.identifier' ],
  3099. [/[$?][\w\-\.']*/, 'constructor.identifier' ],
  3100. // whitespace
  3101. { include: '@whitespace' },
  3102. // delimiters and operators
  3103. [/[()\[\]]/, '@brackets'],
  3104. [/@symbols/, { cases: { '@operators': 'predefined.operator',
  3105. '@default' : 'operator' } } ],
  3106. // numbers
  3107. [/\d*\.\d+([eE][\-+]?\d+)?/, 'number.float'],
  3108. [/0[xX][0-9a-fA-F]+/, 'number.hex'],
  3109. [/#[xX][0-9a-fA-F]+/, 'number.hex'],
  3110. [/#b[0-1]+/, 'number.binary'],
  3111. [/\d+/, 'number'],
  3112. // delimiter: after number because of .\d floats
  3113. [/[,.]/, 'delimiter'],
  3114. // strings
  3115. [/"([^"\\]|\\.)*$/, 'string.invalid' ], // non-teminated string
  3116. [/"/, { token: 'string.quote', bracket: '@open', next: '@string' } ],
  3117. // user values
  3118. [/\{/, { token: 'string.curly', bracket: '@open', next: '@uservalue' } ],
  3119. ],
  3120. uservalue: [
  3121. [/[^\\\}]+/, 'string' ],
  3122. [/\}/, { token: 'string.curly', bracket: '@close', next: '@pop' } ],
  3123. [/\\\}/, 'string.escape'],
  3124. [/./, 'string'] // recover
  3125. ],
  3126. string: [
  3127. [/[^\\"]+/, 'string'],
  3128. [/@escapes/, 'string.escape'],
  3129. [/\\./, 'string.escape.invalid'],
  3130. [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' } ]
  3131. ],
  3132. whitespace: [
  3133. [/[ \t\r\n]+/, 'white'],
  3134. [/;.*$/, 'comment'],
  3135. ],
  3136. },
  3137. };
  3138. </pre
  3139. >
  3140. <pre id="xdot-sample">
  3141. digraph "If.try_if_then"
  3142. {
  3143. label = "If.try_if_then";
  3144. rankdir="TD";
  3145. node [fontname="Helvetica", shape=record, fontsize="12", color="lightblue", style="filled"];
  3146. edge [fontname="Helvetica", fontsize="10", color="black"];
  3147. subgraph "cluster_node_57"
  3148. { /* block node_57 */
  3149. label = "";
  3150. node_57 [label = "Block [57]"];
  3151. node_58 [label = "Return [58@57]"];
  3152. node_50 -> node_58 [label = "mem", dir = back];
  3153. node_48 -> node_58 [label = "int", dir = back];
  3154. } /* block node_57 */
  3155. subgraph "cluster_node_43"
  3156. { /* block node_43 */
  3157. label = "";
  3158. node_43 [label = "Block [43]"];
  3159. node_50 [label = "Proj (mem) [50@43]"];
  3160. node_45 -> node_50 [label = "tuple", dir = back];
  3161. node_49 [label = "Proj (arg_2) [49@43]"];
  3162. node_45 -> node_49 [label = "tuple", dir = back];
  3163. node_48 [label = "Proj (arg_1) [48@43]"];
  3164. node_45 -> node_48 [label = "tuple", dir = back];
  3165. node_45 [label = "Start [45@43]"];
  3166. node_51 [label = "Proj (exe(4)) [51@43]"];
  3167. node_45 -> node_51 [label = "tuple", dir = back];
  3168. } /* block node_43 */
  3169. subgraph "cluster_node_52"
  3170. { /* block node_52 */
  3171. label = "";
  3172. node_52 [label = "Block [52]"];
  3173. node_56 [label = "Proj (exe(0)) [56@52]"];
  3174. node_54 -> node_56 [label = "tuple", dir = back];
  3175. node_53 [label = "Compare [53@52]"];
  3176. node_48 -> node_53 [label = "int", dir = back];
  3177. node_49 -> node_53 [label = "int", dir = back];
  3178. node_54 [label = "Cond (2) [54@52]"];
  3179. node_53 -> node_54 [label = "condition", dir = back];
  3180. node_55 [label = "Proj (exe(1)) [55@52]"];
  3181. node_54 -> node_55 [label = "tuple", dir = back];
  3182. } /* block node_52 */
  3183. subgraph "cluster_node_60"
  3184. { /* block node_60 */
  3185. label = "";
  3186. node_60 [label = "Block [60]"];
  3187. node_61 [label = "Return [61@60]"];
  3188. node_50 -> node_61 [label = "mem", dir = back];
  3189. node_49 -> node_61 [label = "int", dir = back];
  3190. } /* block node_60 */
  3191. subgraph "cluster_node_44"
  3192. { /* block node_44 */
  3193. label = "";
  3194. node_44 [label = "Block [44]"];
  3195. node_46 [label = "End [46@44]"];
  3196. } /* block node_44 */
  3197. node_56 -> node_60 [label = "exe", dir = back];
  3198. node_51 -> node_52 [label = "exe", dir = back];
  3199. node_55 -> node_57 [label = "exe", dir = back];
  3200. node_58 -> node_44 [label = "exe", dir = back];
  3201. node_61 -> node_44 [label = "exe", dir = back];
  3202. } /* Graph "If.try_if_then" */
  3203. </pre
  3204. >
  3205. <pre id="xdot">
  3206. // Difficulty: Easy
  3207. // Dot graph language.
  3208. // See http://www.rise4fun.com/Agl
  3209. return {
  3210. // Set defaultToken to invalid to see what you do not tokenize yet
  3211. // defaultToken: 'invalid',
  3212. keywords: [
  3213. 'strict','graph','digraph','node','edge','subgraph','rank','abstract',
  3214. 'n','ne','e','se','s','sw','w','nw','c','_',
  3215. '-&gt;',':','=',',',
  3216. ],
  3217. builtins: [
  3218. 'rank','rankdir','ranksep','size','ratio',
  3219. 'label','headlabel','taillabel',
  3220. 'arrowhead','samehead','samearrowhead',
  3221. 'arrowtail','sametail','samearrowtail','arrowsize',
  3222. 'labeldistance', 'labelangle', 'labelfontsize',
  3223. 'dir','width','height','angle',
  3224. 'fontsize','fontcolor', 'same','weight','color',
  3225. 'bgcolor','style','shape','fillcolor','nodesep','id',
  3226. ],
  3227. attributes: [
  3228. 'doublecircle','circle','diamond','box','point','ellipse','record',
  3229. 'inv','invdot','dot','dashed','dotted','filled','back','forward',
  3230. ],
  3231. // we include these common regular expressions
  3232. symbols: /[=&gt;&lt;!~?:&amp;|+\-*\/\^%]+/,
  3233. // The main tokenizer for our languages
  3234. tokenizer: {
  3235. root: [
  3236. // identifiers and keywords
  3237. [/[a-zA-Z_\x80-\xFF][\w\x80-\xFF]*/, {
  3238. cases: { '@keywords': 'keyword',
  3239. '@builtins': 'predefined',
  3240. '@attributes': 'constructor',
  3241. '@default': 'identifier' } }],
  3242. // whitespace
  3243. { include: '@whitespace' },
  3244. // html identifiers
  3245. [/&lt;(?!@symbols)/, { token: 'string.html.quote', bracket: '@open', next: 'html' } ],
  3246. // delimiters and operators
  3247. [/[{}()\[\]]/, '@brackets'],
  3248. [/@symbols/, { cases: { '@keywords': 'keyword',
  3249. '@default' : 'operator' } } ],
  3250. // delimiter
  3251. [/[;,]/, 'delimiter'],
  3252. // numbers
  3253. [/\d*\.\d+([eE][\-+]?\d+)?/, 'number.float'],
  3254. [/0[xX][0-9a-fA-F]+/, 'number.hex'],
  3255. [/\d+/, 'number'],
  3256. // strings
  3257. [/"([^"\\]|\\.)*$/, 'string.invalid' ], // non-teminated string
  3258. [/"/, { token: 'string.quote', bracket: '@open', next: '@string' } ],
  3259. ],
  3260. comment: [
  3261. [/[^\/*]+/, 'comment' ],
  3262. [/\/\*/, 'comment', '@push' ], // nested comment
  3263. ["\\*/", 'comment', '@pop' ],
  3264. [/[\/*]/, 'comment' ]
  3265. ],
  3266. html: [
  3267. [/[^&lt;&gt;&amp;]+/, 'string.html'],
  3268. [/&amp;\w+;/, 'string.html.escape' ],
  3269. [/&amp;/, 'string.html'],
  3270. [/&lt;/, { token: 'string.html.quote', bracket: '@open', next: '@push' } ], //nested bracket
  3271. [/&gt;/, { token: 'string.html.quote', bracket: '@close', next: '@pop' } ],
  3272. ],
  3273. string: [
  3274. [/[^\\"&amp;]+/, 'string'],
  3275. [/\\"/, 'string.escape'],
  3276. [/&amp;\w+;/, 'string.escape'],
  3277. [/[\\&amp;]/, 'string'],
  3278. [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' } ]
  3279. ],
  3280. whitespace: [
  3281. [/[ \t\r\n]+/, 'white'],
  3282. [/\/\*/, 'comment', '@comment' ],
  3283. [/\/\/.*$/, 'comment'],
  3284. [/#.*$/, 'comment'],
  3285. ],
  3286. },
  3287. };
  3288. </pre
  3289. >
  3290. <pre id="csharp-sample">
  3291. // CSharp 4.0 ray-tracer sample by Luke Hoban
  3292. using System.Drawing;
  3293. using System.Linq;
  3294. using System;
  3295. using System.Collections.Generic;
  3296. using System.Diagnostics;
  3297. using System.Windows.Forms;
  3298. namespace RayTracer {
  3299. public class RayTracer {
  3300. private int screenWidth;
  3301. private int screenHeight;
  3302. private const int MaxDepth = 5;
  3303. public Action&lt;int, int, System.Drawing.Color> setPixel;
  3304. public RayTracer(int screenWidth, int screenHeight, Action&lt;int,int, System.Drawing.Color> setPixel) {
  3305. this.screenWidth = screenWidth;
  3306. this.screenHeight = screenHeight;
  3307. this.setPixel = setPixel;
  3308. }
  3309. private IEnumerable&lt;ISect> Intersections(Ray ray, Scene scene)
  3310. {
  3311. return scene.Things
  3312. .Select(obj => obj.Intersect(ray))
  3313. .Where(inter => inter != null)
  3314. .OrderBy(inter => inter.Dist);
  3315. }
  3316. private double TestRay(Ray ray, Scene scene) {
  3317. var isects = Intersections(ray, scene);
  3318. ISect isect = isects.FirstOrDefault();
  3319. if (isect == null)
  3320. return 0;
  3321. return isect.Dist;
  3322. }
  3323. private Color TraceRay(Ray ray, Scene scene, int depth) {
  3324. var isects = Intersections(ray, scene);
  3325. ISect isect = isects.FirstOrDefault();
  3326. if (isect == null)
  3327. return Color.Background;
  3328. return Shade(isect, scene, depth);
  3329. }
  3330. private Color GetNaturalColor(SceneObject thing, Vector pos, Vector norm, Vector rd, Scene scene) {
  3331. Color ret = Color.Make(0, 0, 0);
  3332. foreach (Light light in scene.Lights) {
  3333. Vector ldis = Vector.Minus(light.Pos, pos);
  3334. Vector livec = Vector.Norm(ldis);
  3335. double neatIsect = TestRay(new Ray() { Start = pos, Dir = livec }, scene);
  3336. bool isInShadow = !((neatIsect > Vector.Mag(ldis)) || (neatIsect == 0));
  3337. if (!isInShadow) {
  3338. double illum = Vector.Dot(livec, norm);
  3339. Color lcolor = illum > 0 ? Color.Times(illum, light.Color) : Color.Make(0, 0, 0);
  3340. double specular = Vector.Dot(livec, Vector.Norm(rd));
  3341. Color scolor = specular > 0 ? Color.Times(Math.Pow(specular, thing.Surface.Roughness), light.Color) : Color.Make(0, 0, 0);
  3342. ret = Color.Plus(ret, Color.Plus(Color.Times(thing.Surface.Diffuse(pos), lcolor),
  3343. Color.Times(thing.Surface.Specular(pos), scolor)));
  3344. }
  3345. }
  3346. return ret;
  3347. }
  3348. private Color GetReflectionColor(SceneObject thing, Vector pos, Vector norm, Vector rd, Scene scene, int depth) {
  3349. return Color.Times(thing.Surface.Reflect(pos), TraceRay(new Ray() { Start = pos, Dir = rd }, scene, depth + 1));
  3350. }
  3351. private Color Shade(ISect isect, Scene scene, int depth) {
  3352. var d = isect.Ray.Dir;
  3353. var pos = Vector.Plus(Vector.Times(isect.Dist, isect.Ray.Dir), isect.Ray.Start);
  3354. var normal = isect.Thing.Normal(pos);
  3355. var reflectDir = Vector.Minus(d, Vector.Times(2 * Vector.Dot(normal, d), normal));
  3356. Color ret = Color.DefaultColor;
  3357. ret = Color.Plus(ret, GetNaturalColor(isect.Thing, pos, normal, reflectDir, scene));
  3358. if (depth >= MaxDepth) {
  3359. return Color.Plus(ret, Color.Make(.5, .5, .5));
  3360. }
  3361. return Color.Plus(ret, GetReflectionColor(isect.Thing, Vector.Plus(pos, Vector.Times(.001, reflectDir)), normal, reflectDir, scene, depth));
  3362. }
  3363. private double RecenterX(double x) {
  3364. return (x - (screenWidth / 2.0)) / (2.0 * screenWidth);
  3365. }
  3366. private double RecenterY(double y) {
  3367. return -(y - (screenHeight / 2.0)) / (2.0 * screenHeight);
  3368. }
  3369. private Vector GetPoint(double x, double y, Camera camera) {
  3370. return Vector.Norm(Vector.Plus(camera.Forward, Vector.Plus(Vector.Times(RecenterX(x), camera.Right),
  3371. Vector.Times(RecenterY(y), camera.Up))));
  3372. }
  3373. internal void Render(Scene scene) {
  3374. for (int y = 0; y &lt; screenHeight; y++)
  3375. {
  3376. for (int x = 0; x &lt; screenWidth; x++)
  3377. {
  3378. Color color = TraceRay(new Ray() { Start = scene.Camera.Pos, Dir = GetPoint(x, y, scene.Camera) }, scene, 0);
  3379. setPixel(x, y, color.ToDrawingColor());
  3380. }
  3381. }
  3382. }
  3383. internal readonly Scene DefaultScene =
  3384. new Scene() {
  3385. Things = new SceneObject[] {
  3386. new Plane() {
  3387. Norm = Vector.Make(0,1,0),
  3388. Offset = 0,
  3389. Surface = Surfaces.CheckerBoard
  3390. },
  3391. new Sphere() {
  3392. Center = Vector.Make(0,1,0),
  3393. Radius = 1,
  3394. Surface = Surfaces.Shiny
  3395. },
  3396. new Sphere() {
  3397. Center = Vector.Make(-1,.5,1.5),
  3398. Radius = .5,
  3399. Surface = Surfaces.Shiny
  3400. }},
  3401. Lights = new Light[] {
  3402. new Light() {
  3403. Pos = Vector.Make(-2,2.5,0),
  3404. Color = Color.Make(.49,.07,.07)
  3405. },
  3406. new Light() {
  3407. Pos = Vector.Make(1.5,2.5,1.5),
  3408. Color = Color.Make(.07,.07,.49)
  3409. },
  3410. new Light() {
  3411. Pos = Vector.Make(1.5,2.5,-1.5),
  3412. Color = Color.Make(.07,.49,.071)
  3413. },
  3414. new Light() {
  3415. Pos = Vector.Make(0,3.5,0),
  3416. Color = Color.Make(.21,.21,.35)
  3417. }},
  3418. Camera = Camera.Create(Vector.Make(3,2,4), Vector.Make(-1,.5,0))
  3419. };
  3420. }
  3421. static class Surfaces {
  3422. // Only works with X-Z plane.
  3423. public static readonly Surface CheckerBoard =
  3424. new Surface() {
  3425. Diffuse = pos => ((Math.Floor(pos.Z) + Math.Floor(pos.X)) % 2 != 0)
  3426. ? Color.Make(1,1,1)
  3427. : Color.Make(0,0,0),
  3428. Specular = pos => Color.Make(1,1,1),
  3429. Reflect = pos => ((Math.Floor(pos.Z) + Math.Floor(pos.X)) % 2 != 0)
  3430. ? .1
  3431. : .7,
  3432. Roughness = 150
  3433. };
  3434. public static readonly Surface Shiny =
  3435. new Surface() {
  3436. Diffuse = pos => Color.Make(1,1,1),
  3437. Specular = pos => Color.Make(.5,.5,.5),
  3438. Reflect = pos => .6,
  3439. Roughness = 50
  3440. };
  3441. }
  3442. class Vector {
  3443. public double X;
  3444. public double Y;
  3445. public double Z;
  3446. public Vector(double x, double y, double z) { X = x; Y = y; Z = z; }
  3447. public Vector(string str) {
  3448. string[] nums = str.Split(',');
  3449. if (nums.Length != 3) throw new ArgumentException();
  3450. X = double.Parse(nums[0]);
  3451. Y = double.Parse(nums[1]);
  3452. Z = double.Parse(nums[2]);
  3453. }
  3454. public static Vector Make(double x, double y, double z) { return new Vector(x, y, z); }
  3455. public static Vector Times(double n, Vector v) {
  3456. return new Vector(v.X * n, v.Y * n, v.Z * n);
  3457. }
  3458. public static Vector Minus(Vector v1, Vector v2) {
  3459. return new Vector(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z);
  3460. }
  3461. public static Vector Plus(Vector v1, Vector v2) {
  3462. return new Vector(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z);
  3463. }
  3464. public static double Dot(Vector v1, Vector v2) {
  3465. return (v1.X * v2.X) + (v1.Y * v2.Y) + (v1.Z * v2.Z);
  3466. }
  3467. public static double Mag(Vector v) { return Math.Sqrt(Dot(v, v)); }
  3468. public static Vector Norm(Vector v) {
  3469. double mag = Mag(v);
  3470. double div = mag == 0 ? double.PositiveInfinity : 1 / mag;
  3471. return Times(div, v);
  3472. }
  3473. public static Vector Cross(Vector v1, Vector v2) {
  3474. return new Vector(((v1.Y * v2.Z) - (v1.Z * v2.Y)),
  3475. ((v1.Z * v2.X) - (v1.X * v2.Z)),
  3476. ((v1.X * v2.Y) - (v1.Y * v2.X)));
  3477. }
  3478. public static bool Equals(Vector v1, Vector v2) {
  3479. return (v1.X == v2.X) &amp;&amp; (v1.Y == v2.Y) &amp;&amp; (v1.Z == v2.Z);
  3480. }
  3481. }
  3482. public class Color {
  3483. public double R;
  3484. public double G;
  3485. public double B;
  3486. public Color(double r, double g, double b) { R = r; G = g; B = b; }
  3487. public Color(string str) {
  3488. string[] nums = str.Split(',');
  3489. if (nums.Length != 3) throw new ArgumentException();
  3490. R = double.Parse(nums[0]);
  3491. G = double.Parse(nums[1]);
  3492. B = double.Parse(nums[2]);
  3493. }
  3494. public static Color Make(double r, double g, double b) { return new Color(r, g, b); }
  3495. public static Color Times(double n, Color v) {
  3496. return new Color(n * v.R, n * v.G, n * v.B);
  3497. }
  3498. public static Color Times(Color v1, Color v2) {
  3499. return new Color(v1.R * v2.R, v1.G * v2.G,v1.B * v2.B);
  3500. }
  3501. public static Color Plus(Color v1, Color v2) {
  3502. return new Color(v1.R + v2.R, v1.G + v2.G,v1.B + v2.B);
  3503. }
  3504. public static Color Minus(Color v1, Color v2) {
  3505. return new Color(v1.R - v2.R, v1.G - v2.G,v1.B - v2.B);
  3506. }
  3507. public static readonly Color Background = Make(0, 0, 0);
  3508. public static readonly Color DefaultColor = Make(0, 0, 0);
  3509. public double Legalize(double d) {
  3510. return d > 1 ? 1 : d;
  3511. }
  3512. internal System.Drawing.Color ToDrawingColor() {
  3513. return System.Drawing.Color.FromArgb((int)(Legalize(R) * 255), (int)(Legalize(G) * 255), (int)(Legalize(B) * 255));
  3514. }
  3515. }
  3516. class Ray {
  3517. public Vector Start;
  3518. public Vector Dir;
  3519. }
  3520. class ISect {
  3521. public SceneObject Thing;
  3522. public Ray Ray;
  3523. public double Dist;
  3524. }
  3525. class Surface {
  3526. public Func&lt;Vector, Color> Diffuse;
  3527. public Func&lt;Vector, Color> Specular;
  3528. public Func&lt;Vector, double> Reflect;
  3529. public double Roughness;
  3530. }
  3531. class Camera {
  3532. public Vector Pos;
  3533. public Vector Forward;
  3534. public Vector Up;
  3535. public Vector Right;
  3536. public static Camera Create(Vector pos, Vector lookAt) {
  3537. Vector forward = Vector.Norm(Vector.Minus(lookAt, pos));
  3538. Vector down = new Vector(0, -1, 0);
  3539. Vector right = Vector.Times(1.5, Vector.Norm(Vector.Cross(forward, down)));
  3540. Vector up = Vector.Times(1.5, Vector.Norm(Vector.Cross(forward, right)));
  3541. return new Camera() { Pos = pos, Forward = forward, Up = up, Right = right };
  3542. }
  3543. }
  3544. class Light {
  3545. public Vector Pos;
  3546. public Color Color;
  3547. }
  3548. abstract class SceneObject {
  3549. public Surface Surface;
  3550. public abstract ISect Intersect(Ray ray);
  3551. public abstract Vector Normal(Vector pos);
  3552. }
  3553. class Sphere : SceneObject {
  3554. public Vector Center;
  3555. public double Radius;
  3556. public override ISect Intersect(Ray ray) {
  3557. Vector eo = Vector.Minus(Center, ray.Start);
  3558. double v = Vector.Dot(eo, ray.Dir);
  3559. double dist;
  3560. if (v &lt; 0) {
  3561. dist = 0;
  3562. }
  3563. else {
  3564. double disc = Math.Pow(Radius,2) - (Vector.Dot(eo, eo) - Math.Pow(v,2));
  3565. dist = disc &lt; 0 ? 0 : v - Math.Sqrt(disc);
  3566. }
  3567. if (dist == 0) return null;
  3568. return new ISect() {
  3569. Thing = this,
  3570. Ray = ray,
  3571. Dist = dist};
  3572. }
  3573. public override Vector Normal(Vector pos) {
  3574. return Vector.Norm(Vector.Minus(pos, Center));
  3575. }
  3576. }
  3577. class Plane : SceneObject {
  3578. public Vector Norm;
  3579. public double Offset;
  3580. public override ISect Intersect(Ray ray) {
  3581. double denom = Vector.Dot(Norm, ray.Dir);
  3582. if (denom > 0) return null;
  3583. return new ISect() {
  3584. Thing = this,
  3585. Ray = ray,
  3586. Dist = (Vector.Dot(Norm, ray.Start) + Offset) / (-denom)};
  3587. }
  3588. public override Vector Normal(Vector pos) {
  3589. return Norm;
  3590. }
  3591. }
  3592. class Scene {
  3593. public SceneObject[] Things;
  3594. public Light[] Lights;
  3595. public Camera Camera;
  3596. public IEnumerable&lt;ISect> Intersect(Ray r) {
  3597. return from thing in Things
  3598. select thing.Intersect(r);
  3599. }
  3600. }
  3601. public delegate void Action&lt;T,U,V>(T t, U u, V v);
  3602. public partial class RayTracerForm : Form
  3603. {
  3604. Bitmap bitmap;
  3605. PictureBox pictureBox;
  3606. const int width = 600;
  3607. const int height = 600;
  3608. public RayTracerForm()
  3609. {
  3610. bitmap = new Bitmap(width,height);
  3611. pictureBox = new PictureBox();
  3612. pictureBox.Dock = DockStyle.Fill;
  3613. pictureBox.SizeMode = PictureBoxSizeMode.StretchImage;
  3614. pictureBox.Image = bitmap;
  3615. ClientSize = new System.Drawing.Size(width, height + 24);
  3616. Controls.Add(pictureBox);
  3617. Text = "Ray Tracer";
  3618. Load += RayTracerForm_Load;
  3619. Show();
  3620. }
  3621. private void RayTracerForm_Load(object sender, EventArgs e)
  3622. {
  3623. this.Show();
  3624. RayTracer rayTracer = new RayTracer(width, height, (int x, int y, System.Drawing.Color color) =>
  3625. {
  3626. bitmap.SetPixel(x, y, color);
  3627. if (x == 0) pictureBox.Refresh();
  3628. });
  3629. rayTracer.Render(rayTracer.DefaultScene);
  3630. pictureBox.Invalidate();
  3631. }
  3632. [STAThread]
  3633. static void Main() {
  3634. Application.EnableVisualStyles();
  3635. Application.Run(new RayTracerForm());
  3636. }
  3637. }
  3638. }
  3639. </pre
  3640. >
  3641. <pre id="csharp">
  3642. // Difficulty: Moderate
  3643. // CSharp language definition
  3644. // Takes special care to color types and namespaces nicely.
  3645. // (note: this can't be done completely accurately though on a lexical level,
  3646. // but we are getting quite close :-) )
  3647. //
  3648. // Todo: support unicode identifiers
  3649. // Todo: special color for documentation comments and attributes
  3650. return {
  3651. defaultToken: '',
  3652. tokenPostfix: '.cs',
  3653. brackets: [
  3654. { open: '{', close: '}', token: 'delimiter.curly' },
  3655. { open: '[', close: ']', token: 'delimiter.square' },
  3656. { open: '(', close: ')', token: 'delimiter.parenthesis' },
  3657. { open: '&lt;', close: '&gt;', token: 'delimiter.angle' }
  3658. ],
  3659. keywords: [
  3660. 'extern', 'alias', 'using', 'bool', 'decimal', 'sbyte', 'byte', 'short',
  3661. 'ushort', 'int', 'uint', 'long', 'ulong', 'char', 'float', 'double',
  3662. 'object', 'dynamic', 'string', 'assembly', 'is', 'as', 'ref',
  3663. 'out', 'this', 'base', 'new', 'typeof', 'void', 'checked', 'unchecked',
  3664. 'default', 'delegate', 'var', 'const', 'if', 'else', 'switch', 'case',
  3665. 'while', 'do', 'for', 'foreach', 'in', 'break', 'continue', 'goto',
  3666. 'return', 'throw', 'try', 'catch', 'finally', 'lock', 'yield', 'from',
  3667. 'let', 'where', 'join', 'on', 'equals', 'into', 'orderby', 'ascending',
  3668. 'descending', 'select', 'group', 'by', 'namespace', 'partial', 'class',
  3669. 'field', 'event', 'method', 'param', 'property', 'public', 'protected',
  3670. 'internal', 'private', 'abstract', 'sealed', 'static', 'struct', 'readonly',
  3671. 'volatile', 'virtual', 'override', 'params', 'get', 'set', 'add', 'remove',
  3672. 'operator', 'true', 'false', 'implicit', 'explicit', 'interface', 'enum',
  3673. 'null', 'async', 'await', 'fixed', 'sizeof', 'stackalloc', 'unsafe', 'nameof',
  3674. 'when'
  3675. ],
  3676. namespaceFollows: [
  3677. 'namespace', 'using',
  3678. ],
  3679. parenFollows: [
  3680. 'if', 'for', 'while', 'switch', 'foreach', 'using', 'catch', 'when'
  3681. ],
  3682. operators: [
  3683. '=', '??', '||', '&amp;&amp;', '|', '^', '&amp;', '==', '!=', '&lt;=', '&gt;=', '&lt;&lt;',
  3684. '+', '-', '*', '/', '%', '!', '~', '++', '--', '+=',
  3685. '-=', '*=', '/=', '%=', '&amp;=', '|=', '^=', '&lt;&lt;=', '&gt;&gt;=', '&gt;&gt;', '=&gt;'
  3686. ],
  3687. symbols: /[=&gt;&lt;!~?:&amp;|+\-*\/\^%]+/,
  3688. // escape sequences
  3689. escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
  3690. // The main tokenizer for our languages
  3691. tokenizer: {
  3692. root: [
  3693. // identifiers and keywords
  3694. [/\@?[a-zA-Z_]\w*/, {
  3695. cases: {
  3696. '@namespaceFollows': { token: 'keyword.$0', next: '@namespace' },
  3697. '@keywords': { token: 'keyword.$0', next: '@qualified' },
  3698. '@default': { token: 'identifier', next: '@qualified' }
  3699. }
  3700. }],
  3701. // whitespace
  3702. { include: '@whitespace' },
  3703. // delimiters and operators
  3704. [/}/, {
  3705. cases: {
  3706. '$S2==interpolatedstring': { token: 'string.quote', next: '@pop' },
  3707. '$S2==litinterpstring': { token: 'string.quote', next: '@pop' },
  3708. '@default': '@brackets'
  3709. }
  3710. }],
  3711. [/[{}()\[\]]/, '@brackets'],
  3712. [/[&lt;&gt;](?!@symbols)/, '@brackets'],
  3713. [/@symbols/, {
  3714. cases: {
  3715. '@operators': 'delimiter',
  3716. '@default': ''
  3717. }
  3718. }],
  3719. // numbers
  3720. [/[0-9_]*\.[0-9_]+([eE][\-+]?\d+)?[fFdD]?/, 'number.float'],
  3721. [/0[xX][0-9a-fA-F_]+/, 'number.hex'],
  3722. [/0[bB][01_]+/, 'number.hex'], // binary: use same theme style as hex
  3723. [/[0-9_]+/, 'number'],
  3724. // delimiter: after number because of .\d floats
  3725. [/[;,.]/, 'delimiter'],
  3726. // strings
  3727. [/"([^"\\]|\\.)*$/, 'string.invalid'], // non-teminated string
  3728. [/"/, { token: 'string.quote', next: '@string' }],
  3729. [/\$\@"/, { token: 'string.quote', next: '@litinterpstring' }],
  3730. [/\@"/, { token: 'string.quote', next: '@litstring' }],
  3731. [/\$"/, { token: 'string.quote', next: '@interpolatedstring' }],
  3732. // characters
  3733. [/'[^\\']'/, 'string'],
  3734. [/(')(@escapes)(')/, ['string', 'string.escape', 'string']],
  3735. [/'/, 'string.invalid']
  3736. ],
  3737. qualified: [
  3738. [/[a-zA-Z_][\w]*/, {
  3739. cases: {
  3740. '@keywords': { token: 'keyword.$0' },
  3741. '@default': 'identifier'
  3742. }
  3743. }],
  3744. [/\./, 'delimiter'],
  3745. ['', '', '@pop'],
  3746. ],
  3747. namespace: [
  3748. { include: '@whitespace' },
  3749. [/[A-Z]\w*/, 'namespace'],
  3750. [/[\.=]/, 'delimiter'],
  3751. ['', '', '@pop'],
  3752. ],
  3753. comment: [
  3754. [/[^\/*]+/, 'comment'],
  3755. // [/\/\*/, 'comment', '@push' ], // no nested comments :-(
  3756. ['\\*/', 'comment', '@pop'],
  3757. [/[\/*]/, 'comment']
  3758. ],
  3759. string: [
  3760. [/[^\\"]+/, 'string'],
  3761. [/@escapes/, 'string.escape'],
  3762. [/\\./, 'string.escape.invalid'],
  3763. [/"/, { token: 'string.quote', next: '@pop' }]
  3764. ],
  3765. litstring: [
  3766. [/[^"]+/, 'string'],
  3767. [/""/, 'string.escape'],
  3768. [/"/, { token: 'string.quote', next: '@pop' }]
  3769. ],
  3770. litinterpstring: [
  3771. [/[^"{]+/, 'string'],
  3772. [/""/, 'string.escape'],
  3773. [/{{/, 'string.escape'],
  3774. [/}}/, 'string.escape'],
  3775. [/{/, { token: 'string.quote', next: 'root.litinterpstring' }],
  3776. [/"/, { token: 'string.quote', next: '@pop' }]
  3777. ],
  3778. interpolatedstring: [
  3779. [/[^\\"{]+/, 'string'],
  3780. [/@escapes/, 'string.escape'],
  3781. [/\\./, 'string.escape.invalid'],
  3782. [/{{/, 'string.escape'],
  3783. [/}}/, 'string.escape'],
  3784. [/{/, { token: 'string.quote', next: 'root.interpolatedstring' }],
  3785. [/"/, { token: 'string.quote', next: '@pop' }]
  3786. ],
  3787. whitespace: [
  3788. [/^[ \t\v\f]*#((r)|(load))(?=\s)/, 'directive.csx'],
  3789. [/^[ \t\v\f]*#\w.*$/, 'namespace.cpp'],
  3790. [/[ \t\v\f\r\n]+/, ''],
  3791. [/\/\*/, 'comment', '@comment'],
  3792. [/\/\/.*$/, 'comment'],
  3793. ],
  3794. },
  3795. };
  3796. </pre
  3797. >
  3798. <pre id="chalice-sample">
  3799. // This example shows a use of a channel. Properties of the messages
  3800. // passed along the channel, as well as permissions and channel credits,
  3801. // are specified in the channel's "where" clause.
  3802. channel NumberStream(x: int) where 2 &lt;= x ==> credit(this);
  3803. class Sieve {
  3804. method Counter(n: NumberStream, to: int) // sends the plurals along n
  3805. requires rd(n.mu) &amp;&amp; credit(n,-1) &amp;&amp; 0 &lt;= to;
  3806. {
  3807. var i := 2;
  3808. while (i &lt; to)
  3809. invariant rd(n.mu);
  3810. invariant 2 &lt;= i;
  3811. invariant credit(n, -1)
  3812. {
  3813. send n(i);
  3814. i := i + 1;
  3815. }
  3816. send n(-1);
  3817. }
  3818. method Filter(prime: int, r: NumberStream, s: NumberStream)
  3819. requires 2 &lt;= prime;
  3820. requires rd(r.mu) &amp;&amp; waitlevel &lt;&lt; r.mu;
  3821. requires rd(s.mu) &amp;&amp; s.mu &lt;&lt; r.mu &amp;&amp; credit(r) &amp;&amp; credit(s, -1);
  3822. {
  3823. receive x := r;
  3824. while (2 &lt;= x)
  3825. invariant rd(r.mu) &amp;&amp; rd(s.mu) &amp;&amp; s &lt;&lt; r &amp;&amp; waitlevel &lt;&lt; r.mu;
  3826. invariant 2&lt;= x ==> credit(r);
  3827. invariant credit(s, -1);
  3828. {
  3829. if (x % prime != 0) { // suppress multiples of prime
  3830. send s(x);
  3831. }
  3832. receive x := r;
  3833. }
  3834. send s(-1);
  3835. }
  3836. method Start()
  3837. {
  3838. var ch := new NumberStream;
  3839. fork Counter(ch, 101);
  3840. var p: int;
  3841. receive p := ch;
  3842. while (2 &lt;= p)
  3843. invariant ch != null;
  3844. invariant 2 &lt;= p ==> credit(ch, 1);
  3845. invariant rd*(ch.mu) &amp;&amp; waitlevel &lt;&lt; ch.mu;
  3846. {
  3847. // print p--it's a prime!
  3848. var cp := new ChalicePrint; call cp.Int(p);
  3849. var n := new NumberStream between waitlevel and ch;
  3850. fork Filter(p, ch, n);
  3851. ch := n;
  3852. receive p := ch;
  3853. }
  3854. }
  3855. }
  3856. external class ChalicePrint {
  3857. method Int(x: int) { }
  3858. }
  3859. </pre
  3860. >
  3861. <pre id="chalice">
  3862. // Difficulty: "Easy"
  3863. // Language definition sample for the Chalice language.
  3864. // See 'http://rise4fun.com/Chalice'.
  3865. return {
  3866. keywords: [
  3867. 'class','ghost','var','const','method','channel','condition',
  3868. 'assert','assume','new','this','reorder',
  3869. 'between','and','above','below','share','unshare','acquire','release','downgrade',
  3870. 'call','if','else','while','lockchange',
  3871. 'returns','where',
  3872. 'false','true','null',
  3873. 'waitlevel','lockbottom',
  3874. 'module','external',
  3875. 'predicate','function',
  3876. 'forall','exists',
  3877. 'nil','result','eval','token',
  3878. 'unlimited',
  3879. 'refines','transforms','replaces','by','spec',
  3880. ],
  3881. builtins: [
  3882. 'lock','fork','join','rd','acc','credit','holds','old','assigned',
  3883. 'send','receive',
  3884. 'ite','fold','unfold','unfolding','in',
  3885. 'wait','signal',
  3886. ],
  3887. verifyKeywords: [
  3888. 'requires','ensures','free','invariant'
  3889. ],
  3890. types: [
  3891. 'bool','int','string','seq'
  3892. ],
  3893. brackets: [
  3894. ['{','}','delimiter.curly'],
  3895. ['[',']','delimiter.square'],
  3896. ['(',')','delimiter.parenthesis']
  3897. ],
  3898. // Chalice uses C# style strings
  3899. escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
  3900. tokenizer: {
  3901. root: [
  3902. // identifiers
  3903. [/array([2-9]\d*|1\d+)/, 'type.keyword' ],
  3904. [/[a-zA-Z'_\?\\][\w'\?\\]*/, { cases: {'@keywords': 'keyword',
  3905. '@verifyKeywords': 'constructor.identifier',
  3906. '@builtins': 'keyword',
  3907. '@types' : 'type.keyword',
  3908. '@default' : 'identifier' }}],
  3909. [':=','keyword'],
  3910. // whitespace
  3911. { include: '@whitespace' },
  3912. [/[{}()\[\]]/, '@brackets'],
  3913. [/[;,]/, 'delimiter'],
  3914. // literals
  3915. [/[0-9]+/, 'number'],
  3916. // strings
  3917. [/"([^"\\]|\\.)*$/, 'string.invalid' ], // non-teminated string
  3918. [/"/, 'string', '@string' ],
  3919. ],
  3920. whitespace: [
  3921. [/[ \t\r\n]+/, 'white'],
  3922. [/\/\*/, 'comment', '@comment' ],
  3923. [/\/\/.*$/, 'comment'],
  3924. ],
  3925. comment: [
  3926. [/[^\/*]+/, 'comment' ],
  3927. [/\/\*/, 'comment', '@push' ], // nested comment
  3928. ["\\*/", 'comment', '@pop' ],
  3929. [/[\/*]/, 'comment' ]
  3930. ],
  3931. string: [
  3932. [/[^\\"]+/, 'string'],
  3933. [/@escapes/, 'string.escape'],
  3934. [/\\./, 'string.escape.invalid'],
  3935. [/"/, 'string', '@pop' ]
  3936. ],
  3937. }
  3938. };
  3939. </pre
  3940. >
  3941. <pre id="specsharp-sample">
  3942. // This example shows many of the features of Spec#, including pre-
  3943. // and postcondition of methods and object invariants. The basic
  3944. // idea in the example is to implement a "chunker", which returns
  3945. // successive portions of a given string. The main work is done
  3946. // in the NextChunk() method.
  3947. // For a full demo showing this example, check out the "The Chunker"
  3948. // episode on Verification Corner
  3949. // (http://research.microsoft.com/verificationcorner)
  3950. public class Chunker
  3951. {
  3952. string src;
  3953. int ChunkSize;
  3954. invariant 0 &lt;= ChunkSize;
  3955. int n; // the number of characters returned so far
  3956. invariant 0 &lt;= n;
  3957. public string NextChunk()
  3958. ensures result.Length &lt;= ChunkSize;
  3959. {
  3960. string s;
  3961. if (n + ChunkSize &lt;= src.Length) {
  3962. s = src.Substring(n, ChunkSize);
  3963. } else {
  3964. s = src.Substring(n);
  3965. }
  3966. return s;
  3967. }
  3968. public Chunker(string source, int chunkSize)
  3969. {
  3970. src = source;
  3971. ChunkSize = chunkSize;
  3972. n = 0;
  3973. }
  3974. }
  3975. </pre
  3976. >
  3977. <pre id="specsharp">
  3978. // Difficulty: Moderate
  3979. // SpecSharp language definition. This is an extension of the C# language definition.
  3980. // See: http://rise4fun.com/SpecSharp for more information
  3981. //
  3982. // Takes special care to color types and namespaces nicely.
  3983. // (note: this can't be done completely accurately though on a lexical level,
  3984. // but we are getting quite close :-) )
  3985. //
  3986. // Todo: support unicode identifiers
  3987. // Todo: special color for documentation comments and attributes
  3988. return {
  3989. keywords: [
  3990. 'extern', 'alias', 'using', 'bool', 'decimal', 'sbyte', 'byte', 'short',
  3991. 'ushort', 'int', 'uint', 'long', 'ulong', 'char', 'float', 'double',
  3992. 'object', 'dynamic', 'string', 'assembly', 'module', 'is', 'as', 'ref',
  3993. 'out', 'this', 'base', 'new', 'typeof', 'void', 'checked', 'unchecked',
  3994. 'default', 'delegate', 'var', 'const', 'if', 'else', 'switch', 'case',
  3995. 'while', 'do', 'for', 'foreach', 'in', 'break', 'continue', 'goto',
  3996. 'return', 'throw', 'try', 'catch', 'finally', 'lock', 'yield', 'from',
  3997. 'let', 'where', 'join', 'on', 'equals', 'into', 'orderby', 'ascending',
  3998. 'descending', 'select', 'group', 'by', 'namespace', 'partial', 'class',
  3999. 'field', 'event', 'method', 'param', 'property', 'public', 'protected',
  4000. 'internal', 'private', 'abstract', 'sealed', 'static', 'struct', 'readonly',
  4001. 'volatile', 'virtual', 'override', 'params', 'get', 'set', 'add', 'remove',
  4002. 'operator', 'true', 'false', 'implicit', 'explicit', 'interface', 'enum',
  4003. 'null',
  4004. '=',':',
  4005. 'expose', 'assert', 'assume',
  4006. 'additive', 'model', 'throws',
  4007. 'forall', 'exists', 'unique', 'count', 'max', 'min', 'product', 'sum',
  4008. 'result'
  4009. ],
  4010. verifyKeywords: [
  4011. 'requires', 'modifies', 'ensures', 'otherwise', 'satisfies', 'witness', 'invariant',
  4012. ],
  4013. typeKeywords: [
  4014. 'bool', 'byte', 'char', 'decimal', 'double', 'fixed', 'float',
  4015. 'int', 'long','object','sbyte','short','string','uint','ulong',
  4016. 'ushort','void'
  4017. ],
  4018. keywordInType: [
  4019. 'struct','new','where','class'
  4020. ],
  4021. typeFollows: [
  4022. 'as', 'class', 'interface', 'struct', 'enum', 'new','where',
  4023. ':',
  4024. ],
  4025. namespaceFollows: [
  4026. 'namespace', 'using',
  4027. ],
  4028. operators: [
  4029. '??', '||', '&amp;&amp;', '|', '^', '&amp;', '==', '!=', '&lt;=', '&gt;=', '&lt;&lt;',
  4030. '+', '-', '*', '/', '%', '!', '~', '++', '--','+=',
  4031. '-=', '*=', '/=', '%=', '&amp;=', '|=', '^=', '&lt;&lt;=', '&gt;&gt;=', '&gt;&gt;', '=&gt;'
  4032. ],
  4033. symbols: /[=&gt;&lt;!~?:&amp;|+\-*\/\^%]+/,
  4034. // escape sequences
  4035. escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
  4036. // The main tokenizer for our languages
  4037. tokenizer: {
  4038. root: [
  4039. // Try to show type names nicely: for parameters: Type name
  4040. [/[A-Z][\w]*(?=[\.\w]*(\s|\/\*!\*\/)+\w)/, 'type.identifier' ],
  4041. // Generic types List&lt;int&gt;.
  4042. // Unfortunately, colors explicit nested generic method instantiation as Method&lt;List&lt;int&gt;&gt;(x) wrongly
  4043. [/([A-Z][\w]*[\.\w]*)(&lt;)(?![^&gt;]+&gt;\s*(?:\(|$))/, ['type.identifier', { token: '@brackets', next: '@type' } ]],
  4044. [/([A-Z][\w]*[\.\w]*)(&lt;)/, ['identifier', { token: '@brackets', next: '@type' } ]],
  4045. // These take care of 'System.Console.WriteLine'.
  4046. // These two rules are not 100% right: if a non-qualified field has an uppercase name
  4047. // it colors it as a type.. but you could use this.Field to circumenvent this.
  4048. [/[A-Z][\w]*(?=\.[A-Z])/, 'type.identifier' ],
  4049. [/[A-Z][\w]*(?=\.[a-z_])/, 'type.identifier', '@qualified' ],
  4050. // identifiers and keywords
  4051. [/[a-zA-Z_]\w*/, { cases: {'@typeFollows': { token: 'keyword', next: '@type' },
  4052. '@namespaceFollows': { token: 'keyword', next: '@namespace' },
  4053. '@typeKeywords': { token: 'type.identifier', next: '@qualified' },
  4054. '@keywords': { token: 'keyword', next: '@qualified' },
  4055. '@verifyKeywords': { token: 'constructor', next: '@qualified' },
  4056. '@default': { token: 'identifier', next: '@qualified' } } }],
  4057. // whitespace
  4058. { include: '@whitespace' },
  4059. // delimiters and operators
  4060. [/[{}()\[\]]/, '@brackets'],
  4061. [/[&lt;&gt;](?!@symbols)/, '@brackets'],
  4062. [/@symbols/, { cases: { '@operators': 'operator',
  4063. '@default' : '' } } ],
  4064. // literal string
  4065. [/@"/, { token: 'string.quote', bracket: '@open', next: '@litstring' } ],
  4066. // numbers
  4067. [/\d*\.\d+([eE][\-+]?\d+)?/, 'number.float'],
  4068. [/0[xX][0-9a-fA-F]+/, 'number.hex'],
  4069. [/\d+/, 'number'],
  4070. // delimiter: after number because of .\d floats
  4071. [/[;,.]/, 'delimiter'],
  4072. // strings
  4073. [/"([^"\\]|\\.)*$/, 'string.invalid' ], // non-teminated string
  4074. [/"/, { token: 'string.quote', bracket: '@open', next: '@string' } ],
  4075. // characters
  4076. [/'[^\\']'/, 'string'],
  4077. [/(')(@escapes)(')/, ['string','string.escape','string']],
  4078. [/'/, 'string.invalid']
  4079. ],
  4080. qualified: [
  4081. [/[a-zA-Z_][\w]*/, { cases: { '@typeFollows': { token: 'keyword', next: '@type' },
  4082. '@typeKeywords': 'type.identifier',
  4083. '@keywords': 'keyword',
  4084. '@verifyKeywords': 'constructor',
  4085. '@default': 'identifier' } }],
  4086. [/\./, 'delimiter'],
  4087. ['','','@pop'],
  4088. ],
  4089. type: [
  4090. { include: '@whitespace' },
  4091. [/[A-Z]\w*/, 'type.identifier'],
  4092. // identifiers and keywords
  4093. [/[a-zA-Z_]\w*/, { cases: {'@typeKeywords': 'type.identifier',
  4094. '@keywordInType': 'keyword',
  4095. '@keywords': {token: '@rematch', next: '@popall'},
  4096. '@verifyKeywords': {token: '@rematch', next: '@popall'},
  4097. '@default': 'type.identifier' } }],
  4098. [/[&lt;]/, '@brackets', '@type_nested' ],
  4099. [/[&gt;]/, '@brackets', '@pop' ],
  4100. [/[\.,:]/, { cases: { '@keywords': 'keyword',
  4101. '@verifyKeywords': 'constructor',
  4102. '@default': 'delimiter' }}],
  4103. ['','','@popall'], // catch all
  4104. ],
  4105. type_nested: [
  4106. [/[&lt;]/, '@brackets', '@type_nested' ],
  4107. { include: 'type' }
  4108. ],
  4109. namespace: [
  4110. { include: '@whitespace' },
  4111. [/[A-Z]\w*/, 'namespace'],
  4112. [/[\.=]/, 'keyword'],
  4113. ['','','@pop'],
  4114. ],
  4115. comment: [
  4116. [/[^\/*]+/, 'comment' ],
  4117. // [/\/\*/, 'comment', '@push' ], // no nested comments :-(
  4118. ["\\*/", 'comment', '@pop' ],
  4119. [/[\/*]/, 'comment' ]
  4120. ],
  4121. string: [
  4122. [/[^\\"]+/, 'string'],
  4123. [/@escapes/, 'string.escape'],
  4124. [/\\./, 'string.escape.invalid'],
  4125. [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' } ]
  4126. ],
  4127. litstring: [
  4128. [/[^"]+/, 'string'],
  4129. [/""/, 'string.escape'],
  4130. [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' } ]
  4131. ],
  4132. whitespace: [
  4133. [/^[ \t\v\f]*#\w.*$/, 'namespace.cpp' ],
  4134. [/[ \t\v\f\r\n]+/, 'white'],
  4135. [/\/\*/, 'comment', '@comment' ],
  4136. [/\/\/.*$/, 'comment'],
  4137. ],
  4138. },
  4139. };</pre
  4140. >
  4141. <pre id="boogie-sample">
  4142. // The partition step of Quick Sort picks a 'pivot' element from a specified subsection
  4143. // of a given integer array. It then partially sorts the elements of the array so that
  4144. // elements smaller than the pivot end up to the left of the pivot and elements larger
  4145. // than the pivot end up to the right of the pivot. Finally, the index of the pivot is
  4146. // returned.
  4147. // The procedure below always picks the first element of the subregion as the pivot.
  4148. // The specification of the procedure talks about the ordering of the elements, but
  4149. // does not say anything about keeping the multiset of elements the same.
  4150. var A: [int]int;
  4151. const N: int;
  4152. procedure Partition(l: int, r: int) returns (result: int)
  4153. requires 0 &lt;= l &amp;&amp; l+2 &lt;= r &amp;&amp; r &lt;= N;
  4154. modifies A;
  4155. ensures l &lt;= result &amp;&amp; result &lt; r;
  4156. ensures (forall k: int, j: int :: l &lt;= k &amp;&amp; k &lt; result &amp;&amp; result &lt;= j &amp;&amp; j &lt; r ==> A[k] &lt;= A[j]);
  4157. ensures (forall k: int :: l &lt;= k &amp;&amp; k &lt; result ==> A[k] &lt;= old(A)[l]);
  4158. ensures (forall k: int :: result &lt;= k &amp;&amp; k &lt; r ==> old(A)[l] &lt;= A[k]);
  4159. {
  4160. var pv, i, j, tmp: int;
  4161. pv := A[l];
  4162. i := l;
  4163. j := r-1;
  4164. // swap A[l] and A[j]
  4165. tmp := A[l];
  4166. A[l] := A[j];
  4167. A[j] := tmp;
  4168. goto LoopHead;
  4169. // The following loop iterates while 'i &lt; j'. In each iteration,
  4170. // one of the three alternatives (A, B, or C) is chosen in such
  4171. // a way that the assume statements will evaluate to true.
  4172. LoopHead:
  4173. // The following the assert statements give the loop invariant
  4174. assert (forall k: int :: l &lt;= k &amp;&amp; k &lt; i ==> A[k] &lt;= pv);
  4175. assert (forall k: int :: j &lt;= k &amp;&amp; k &lt; r ==> pv &lt;= A[k]);
  4176. assert l &lt;= i &amp;&amp; i &lt;= j &amp;&amp; j &lt; r;
  4177. goto A, B, C, exit;
  4178. A:
  4179. assume i &lt; j;
  4180. assume A[i] &lt;= pv;
  4181. i := i + 1;
  4182. goto LoopHead;
  4183. B:
  4184. assume i &lt; j;
  4185. assume pv &lt;= A[j-1];
  4186. j := j - 1;
  4187. goto LoopHead;
  4188. C:
  4189. assume i &lt; j;
  4190. assume A[j-1] &lt; pv &amp;&amp; pv &lt; A[i];
  4191. // swap A[j-1] and A[i]
  4192. tmp := A[i];
  4193. A[i] := A[j-1];
  4194. A[j-1] := tmp;
  4195. assert A[i] &lt; pv &amp;&amp; pv &lt; A[j-1];
  4196. i := i + 1;
  4197. j := j - 1;
  4198. goto LoopHead;
  4199. exit:
  4200. assume i == j;
  4201. result := i;
  4202. }
  4203. </pre
  4204. >
  4205. <pre id="boogie">
  4206. // Difficulty: "Easy"
  4207. // Language definition sample for the Boogie language.
  4208. // See 'http://rise4fun.com/Boogie'.
  4209. return {
  4210. keywords: [
  4211. 'type','const','function','axiom','var','procedure','implementation',
  4212. 'returns',
  4213. 'assert','assume','break','call','then','else','havoc','if','goto','return','while',
  4214. 'old','forall','exists','lambda','cast',
  4215. 'false','true'
  4216. ],
  4217. verifyKeywords: [
  4218. 'where','requires','ensures','modifies','free','invariant',
  4219. 'unique','extends','complete'
  4220. ],
  4221. types: [
  4222. 'bool','int'
  4223. ],
  4224. escapes: '\\\\(?:[abfnrtv\\\\""\']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})',
  4225. tokenizer: {
  4226. root: [
  4227. // identifiers
  4228. ['bv(0|[1-9]\\d*)', 'type.keyword' ],
  4229. [/\\?[a-zA-Z_'\~#\$\^\.\?\\`][\w_'\~#\$\^\.\?\\`]*(\s*:\s*$)?/,
  4230. { cases: {'$1': 'constructor',
  4231. '@keywords': 'keyword',
  4232. '@verifyKeywords': 'constructor.identifier',
  4233. '@types' : 'type.keyword',
  4234. '@default' : 'identifier' }}],
  4235. [':=','keyword'],
  4236. // whitespace
  4237. { include: '@whitespace' },
  4238. ['[\\{\\}\\(\\)\\[\\]]', '@brackets'],
  4239. ['[;,]', 'delimiter'],
  4240. // literals
  4241. ['[0-9]+bv[0-9]+', 'number'], // this is perhaps not so much a 'number' as it is a 'bitvector literal'
  4242. ['[0-9]+', 'number'],
  4243. ['""$', 'string.invalid'], // recover
  4244. ['""', 'string', '@string' ],
  4245. ],
  4246. whitespace: [
  4247. ['[ \\t\\r\\n]+', 'white'],
  4248. ['/\\*', 'comment', '@comment' ],
  4249. ['//.*', 'comment']
  4250. ],
  4251. comment: [
  4252. ['[^/\\*]+', 'comment' ],
  4253. ['/\\*', 'comment', '@push' ],
  4254. ['\\*/', 'comment', '@pop' ],
  4255. ['[/\\*]', 'comment']
  4256. ],
  4257. string: [
  4258. ['[^\\\\""]+$', 'string.invalid', '@pop'], // recover on end of line
  4259. ['@escapes$', 'string.escape.invalid', '@pop'], // more recovery
  4260. ['[^\\\\""]+', 'string'],
  4261. ['@escapes', 'string.escape'],
  4262. ['""', 'string', '@pop' ]
  4263. ]
  4264. }
  4265. }
  4266. </pre
  4267. >
  4268. <pre id="formula-sample">
  4269. /*
  4270. This Formula specificatin models a problem in graph theory. It tries to find
  4271. a Eulerian walk within a specified graph. The problem is to find a walk through
  4272. the graph with the following properties:
  4273. - all edges in the graph must be used
  4274. - every edge must be used only once
  4275. A well known example of this problem is the so called German "Das-ist-das-Haus-vom-Nikolaus"
  4276. problem, which is modeled within this file.
  4277. */
  4278. domain EulerWay
  4279. {
  4280. primitive BaseEdge ::= (x:PosInteger, y:PosInteger).
  4281. primitive SolutionEdge ::= (pos:PosInteger, x : PosInteger, y : PosInteger).
  4282. // Make sure we have used all BaseEdge terms in the solution
  4283. usedBaseEdge ::= (x:PosInteger, y:PosInteger).
  4284. usedBaseEdge(x,y) :- BaseEdge(x,y), SolutionEdge(_,x,y).
  4285. usedBaseEdge(x,y) :- BaseEdge(x,y), SolutionEdge(_,y,x).
  4286. unusedBaseEdge := BaseEdge(x,y), fail usedBaseEdge(x,y).
  4287. // Make sure our index values are one based and not bigger than the number of base edges
  4288. indexTooBig := SolutionEdge(x,_,_), x > count(BaseEdge(_,_)).
  4289. // Make sure that no index is used twice
  4290. doubleIndex := s1 is SolutionEdge, s2 is SolutionEdge, s1 != s2, s1.pos = s2.pos.
  4291. // Exclude edges that don't line up
  4292. //wrongSequence := SolutionEdge(x, Edge(_,b)), SolutionEdge(y, Edge(c,_)), y = x + 1, b != c.
  4293. wrongSequence := SolutionEdge(pos1,_,y1), SolutionEdge(pos2,x2,_), pos2 = pos1 + 1, y1 != x2.
  4294. // Avoid using edges twice
  4295. doubleEdge := SolutionEdge(pos1,x,y), SolutionEdge(pos2,x,y), pos1 != pos2.
  4296. // Exclude mirrors of already used edges
  4297. mirrorEdge := SolutionEdge(_,x,y), SolutionEdge(_,y,x).
  4298. conforms := !unusedBaseEdge &amp; !indexTooBig &amp; !doubleIndex &amp; !wrongSequence &amp; !doubleEdge &amp; !mirrorEdge.
  4299. }
  4300. /*
  4301. Nikolaus graph:
  4302. 5
  4303. / \
  4304. 3---4
  4305. |\ /|
  4306. | X |
  4307. |/ \|
  4308. 1---2
  4309. */
  4310. partial model nikolaus2 of EulerWay
  4311. {
  4312. BaseEdge(1,2)
  4313. BaseEdge(1,3)
  4314. BaseEdge(1,4)
  4315. BaseEdge(2,4)
  4316. BaseEdge(2,3)
  4317. BaseEdge(3,4)
  4318. BaseEdge(3,5)
  4319. BaseEdge(4,5)
  4320. SolutionEdge(1,_,_)
  4321. SolutionEdge(2,_,_)
  4322. SolutionEdge(3,_,_)
  4323. SolutionEdge(4,_,_)
  4324. SolutionEdge(5,_,_)
  4325. SolutionEdge(6,_,_)
  4326. SolutionEdge(7,_,_)
  4327. SolutionEdge(8,_,_)
  4328. }
  4329. </pre
  4330. >
  4331. <pre id="formula">
  4332. // Difficulty: 'Easy'
  4333. // Language definition for the Formula language
  4334. // More information at: http://rise4fun.com/formula
  4335. return {
  4336. brackets: [
  4337. ['{','}','delimiter.curly'],
  4338. ['[',']','delimiter.square'],
  4339. ['(',')','delimiter.parenthesis']
  4340. ],
  4341. keywords: [
  4342. 'domain', 'model', 'transform', 'system',
  4343. 'includes', 'extends', 'of', 'returns',
  4344. 'at', 'machine', 'is', 'no',
  4345. 'new', 'fun', 'inj', 'bij',
  4346. 'sur', 'any', 'ensures', 'requires',
  4347. 'some', 'atleast', 'atmost', 'partial',
  4348. 'initially', 'next', 'property', 'boot',
  4349. 'primitive'
  4350. ],
  4351. operators: [
  4352. ':', '::', '..', '::=',
  4353. ':-', '|', ';', ',',
  4354. '=', '!=', '&lt;', '&lt;=',
  4355. '&gt;', '&gt;=', '+', '-',
  4356. '%', '/', '*'
  4357. ],
  4358. // operators
  4359. symbols: /([\.]{2})|([=&gt;&lt;!:\|\+\-\*\/%,;]+)/,
  4360. // escape sequences
  4361. escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
  4362. tokenizer: {
  4363. root : [
  4364. { include: '@whitespace' },
  4365. [ /[a-zA-Z_][\w_]*('*)/, {
  4366. cases: {
  4367. '@keywords': 'keyword',
  4368. '@default': 'identifier'
  4369. } } ],
  4370. // delimiters
  4371. [ /[\{\}\(\)\[\]]/, '@brackets' ],
  4372. [ /`/, { token: 'delimiter.quote', next: '@quotation', bracket: "@open" } ],
  4373. [ /\./, 'delimiter' ],
  4374. // numbers
  4375. [ /[\-\+]?\d+\/[\-\+]?\d*[1-9]/, 'string' ],
  4376. [ /[\-\+]?\d+(\.\d+)?/, 'string' ],
  4377. [ /@symbols/, { cases:{ '@operators': 'keyword',
  4378. '@default': 'symbols' } } ],
  4379. // strings
  4380. [/"([^"\\]|\\.)*$/, 'string.invalid' ], // non-teminated string
  4381. [/"/, 'string', '@string' ],
  4382. ],
  4383. unquote: [
  4384. { 'include' : '@root' },
  4385. [ /\$/, 'predefined.identifier', '@pop' ]
  4386. ],
  4387. quotation:
  4388. [
  4389. [ /[^`\$]/, 'metatag' ],
  4390. [ /`/, { token: 'delimiter.quote', bracket: '@close', next: '@pop' } ],
  4391. [ /\$/, 'predefined.identifier', '@unquote' ]
  4392. ],
  4393. whitespace: [
  4394. [/[ \t\r\n]+/, 'white'],
  4395. [/\/\*/, 'comment', '@comment' ],
  4396. [/\/\/.*$/, 'comment'],
  4397. ],
  4398. comment: [
  4399. [/[^\/*]+/, 'comment' ],
  4400. [/\/\*/, 'comment', '@push' ], // nested comments
  4401. [/\/\*/, 'comment.invalid' ],
  4402. ["\\*/", 'comment', '@pop' ],
  4403. [/[\/*]/, 'comment' ]
  4404. ],
  4405. string: [
  4406. [/[^"]+/, 'string'],
  4407. // [/@escapes/, 'string.escape'],
  4408. // [/\\./, 'string.escape.invalid'],
  4409. [/"/, 'string', '@pop' ]
  4410. ],
  4411. }
  4412. };
  4413. </pre
  4414. >
  4415. </div>
  4416. <!-- samples -->
  4417. </section>
  4418. <footer class="container">
  4419. <hr />
  4420. <p class="text-center">
  4421. <small>&copy; {{year}} Microsoft</small>
  4422. </p>
  4423. </footer>
  4424. <script
  4425. src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"
  4426. integrity="sha256-wS9gmOZBqsqWxgIVgA8Y9WcQOa7PgSIX+rPA0VL2rbQ="
  4427. crossorigin="anonymous"
  4428. ></script>
  4429. <script
  4430. src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.0/bootstrap.min.js"
  4431. integrity="sha256-u+l2mGjpmGK/mFgUncmMcFKdMijvV+J3odlDJZSNUu8="
  4432. crossorigin="anonymous"
  4433. ></script>
  4434. <script>
  4435. var require = { paths: { vs: '../release/dev/vs' } };
  4436. </script>
  4437. <script src="../release/dev/vs/loader.js"></script>
  4438. <script src="../release/dev/vs/editor/editor.main.nls.js"></script>
  4439. <script src="../release/dev/vs/editor/editor.main.js"></script>
  4440. <script data-inline="yes-please" src="./monarch/monarch.js"></script>
  4441. </body>
  4442. </html>