monarch-static.html 167 KB

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