package Ġcz . j _ j zk . k lang . lex . re . parsing Ċ Ċ import Ġcz . j _ j zk . k lang . lex . re . Regexp Ċ import Ġcz . j _ j zk . k lang . lex . re . Symbol Ċ Ċ /** Ċ Ġ* ĠParses Ġa Ġlist Ġof Ġregex Ġtokens Ġusing Ġrecursive Ġdesc ent . Ċ Ġ* ĠSee : Ġthe Ġgrammar . Ċ Ġ* Ċ Ġ* Ġ@ throws ĠRegex Parsing Exception Ġif Ġa Ġsyntax Ġerror Ġis Ġdetected . Ċ Ġ*/ Ċ fun Ġparse ( tokens : ĠList < Token >): ĠRegex p Ġ{ ĊĠĠĠ Ġreturn ĠStateful Parser ( tokens ). parse () Ċ } Ċ Ċ class ĠRegex Parsing Exception ( message : ĠString ): ĠException ( message ) Ċ Ċ /** Ċ Ġ* ĠA Ġclass Ġthat Ġuses Ġits Ġstate Ġto Ġtrack Ġthe Ġparsing , Ġhence Ġit 's Ġnot Ċ Ġ* Ġthread - safe . Ċ Ġ*/ Ċ private Ġclass ĠStateful Parser ( tokens : ĠList < Token >) Ġ{ ĊĊĠĠĠ Ġvar Ġtokens It Ġ= Ġtokens . list Iterator () ĊĊĠĠĠ Ġfun Ġparse (): ĠRegex p Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġparsed Expression Ġ= Ġregexp () ĊĠĠĠĠĠĠĠ Ġif Ġ( hasNext ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠRegex Parsing Exception (" Tokens Ġleft Ġover Ġafter Ġattempted Ġparse .") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġparsed Expression ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġregexp (): ĠRegex p Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠThis Ġis Ġcalled Ġinside Ġa Ġgroup , Ġit Ġcan Ġbe Ġ" empty " Ġbut Ġwith Ġcharacters ĊĠĠĠĠĠĠĠ Ġ// Ġstill Ġremaining . ĠWould Ġpossibly Ġbe Ġne ater Ġto Ġallow Ġor () Ġto Ġreturn ĊĠĠĠĠĠĠĠ Ġ// Ġan Ġempty Ġconcat enation . ĊĠĠĠĠĠĠĠ Ġif Ġ(! hasNext () Ġ|| Ġnext Matches ( TokenType . RIGHT _ ROUND _ BRACK ET )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠRegex p . Concatenation () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġor () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġor (): ĠRegex p Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġor Optional ( concat enation ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġor Optional ( left Part : ĠRegex p ): ĠRegex p Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( next Matches ( TokenType . OR )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġskip () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġor Optional ( Regexp . Or ( left Part , Ġconcat enation ())) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġleft Part ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġskip () Ġ{ ĊĠĠĠĠĠĠĠ Ġtokens It . next () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhas Next (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtokens It . hasNext () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġnext Matches ( var arg Ġmatch Types : ĠTokenType ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! hasNext ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġnext : ĠToken Ġ= ĠgetNext () ĊĠĠĠĠĠĠĠ Ġre wind () ĊĠĠĠĠĠĠĠ Ġreturn Ġmatch Types . any Ġ{ Ġit Ġ== Ġnext . type Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġnext Type (): ĠTokenType ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! hasNext ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġtype Ġ= ĠgetNext (). type ĊĠĠĠĠĠĠĠ Ġre wind () ĊĠĠĠĠĠĠĠ Ġreturn Ġtype ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġnext Matches Raw ( match : ĠChar ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! hasNext ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnext Ġ= ĠgetNext () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġre wind () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnext . raw Ġ== Ġmatch ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠgetNext (): ĠToken Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtokens It . next () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġnext OrThrow ( msg : ĠString ): ĠToken Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! hasNext ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠRegex Parsing Exception ( msg ) ĊĊĠĠĠĠĠĠĠ Ġreturn ĠgetNext () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġre wind () Ġ{ ĊĠĠĠĠĠĠĠ Ġtokens It . previous () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġconcat enation (): ĠRegex p Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsub expressions : ĠMutable List < Regexp > Ġ= Ġmutable ListOf () ĊĠĠĠĠĠĠĠ Ġwhile Ġ( next Matches ( TokenType . LEFT _ ROUND _ BRACK ET , ĠTokenType . DOT , ĠTokenType . CHARACTER , ĠTokenType . BACK SL ASH , ĠTokenType . LEFT _ S QUARE _ BRACK ET )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsub expressions . add ( unit ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( sub expressions . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠRegex Parsing Exception (" Expected Ġsymbols Ġbut Ġfound Ġnone .") ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( sub expressions . size Ġ== Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġsub expressions . first () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠRegex p . Concatenation ( sub expressions ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġunit (): ĠRegex p Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġmodifier ( un modified Unit ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġun modified Unit (): ĠRegex p Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġnext : ĠToken Ġ= ĠgetNext () ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen ( next . type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . CHARACTER Ġ-> ĠRegex p . Char Matcher ( Symbol . Raw Character ( next . raw )) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . DOT Ġ-> ĠRegex p . Char Matcher ( Symbol . Dot ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . LEFT _ ROUND _ BRACK ET Ġ-> Ġgroup () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . BACK SL ASH Ġ-> Ġback sl ashed Character () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . LEFT _ S QUARE _ BRACK ET Ġ-> Ġcharacter Range () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠRegex Parsing Exception (" Failed Ġto Ġparse Ġ$ next !") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġmodifier ( expression To Modify : ĠRegex p ): ĠRegex p Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! hasNext ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġexpression To Modify ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġtype Ġ= Ġnext Type () ĊĠĠĠĠĠĠĠ Ġskip () ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . STAR Ġ-> ĠRegex p . Zero Or More Times ( expression To Modify ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . PLUS Ġ-> ĠRegex p . One Or More Times ( expression To Modify ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . QUEST ION _ MARK Ġ-> ĠRegex p . Zero Or One Time ( expression To Modify ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġre wind () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexpression To Modify ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġgroup (): ĠRegex p Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsub expression Ġ= Ġregexp () ĊĠĠĠĠĠĠĠ Ġif Ġ(! next Matches ( TokenType . RIGHT _ ROUND _ BRACK ET )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠRegex Parsing Exception (" Un closed Ġgroup !") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġskip () ĊĠĠĠĠĠĠĠ Ġreturn ĠRegex p . Group ( sub expression ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcharacter Range (): ĠRegex p Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġinverted Ġ= Ġnext Matches Raw (' ^ ') ĊĠĠĠĠĠĠĠ Ġif Ġ( inverted ) Ġskip () ĊĊĠĠĠĠĠĠĠ Ġval Ġsymbol Ġ= Ġif Ġ( inverted ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSymbol . Logical Not ( character Range Definition ()) ĊĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcharacter Range Definition () ĊĊĠĠĠĠĠĠĠ Ġreturn ĠRegex p . Char Matcher ( symbol ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcharacter Range Definition (): ĠSymbol Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcharacters Ġ= Ġmutable ListOf < Char >() ĊĊĠĠĠĠĠĠĠ Ġwhile Ġ( hasNext () Ġ&& Ġ! next Matches ( TokenType . RIGHT _ S QUARE _ BRACK ET )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnext Ġ= Ġnon Special Character ("- ^ ]\ \" . toList ()) Ġ?: Ġthrow ĠRegex Parsing Exception (" Unexpected Ġspecial Ġcharacter Ġin Ġa Ġcharacter Ġrange ") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( next Matches Raw ('- ')) Ġ{ Ġ Ġ// Ġcompreh ension ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġskip () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġend Ġ= Ġnon Special Character ("- ^ ]\ \" . toList ()) Ġ?: Ġthrow ĠRegex Parsing Exception (" Unexpected Ġspecial Ġcharacter Ġafter Ġa Ġhy phen Ġin Ġa Ġcharacter Ġrange ") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( next Ġ> Ġend ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠRegex Parsing Exception (" Bad Ġcompreh ension Ġin Ġa Ġcharacter Ġrange Ġ( first Ġcharacter Ġhas Ġlarger ĠASCII Ġvalue Ġthan Ġthe Ġsecond Ġone )") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcharacters Ġ+= Ġnext Ġ.. Ġend ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcharacters Ġ+= Ġnext ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! next Matches ( TokenType . RIGHT _ S QUARE _ BRACK ET )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠRegex Parsing Exception (" Un closed Ġcharacter Ġrange ") ĊĠĠĠĠĠĠĠ Ġskip () ĊĊĠĠĠĠĠĠĠ Ġreturn ĠSymbol . Any Of ( characters ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġback sl ashed Character (): ĠRegex p Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! hasNext ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠRegex Parsing Exception (" No Ġcharacter Ġafter Ġa Ġback slash !") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġnext Ġ= ĠgetNext () ĊĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnext Ġin Ġspecial Tokens Ġ-> ĠRegex p . Char Matcher ( Symbol . Raw Character ( next . raw )) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠChar Classes . is Single Char Class ( next . raw ) Ġ-> ĠRegex p . Char Matcher ( Char Classes . get Single Char Class ( next . raw ) !! ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠRegex Parsing Exception (" Invalid Ġcharacter Ġafter Ġa Ġback slash : Ġ\\ ${ next . raw }") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠA Ġhelper Ġfunction Ġwhich Ġeither Ġreturns Ġa Ġregular Ġcharacter Ġ( not Ġin ĊĠĠĠĠ Ġ* Ġ` special Chars `) Ġor Ġa Ġback slash - escaped Ġcharacter Ġfrom Ġ` special Chars `. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġnon Special Character ( special Chars : ĠIterable < Char >): ĠChar ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġnext Ġ= Ġnext OrThrow (" Unexpected Ġend Ġof Ġinput !") ĊĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnext . type Ġ== ĠTokenType . BACK SL ASH Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġescaped Ġ= Ġnext OrThrow (" No Ġcharacter Ġafter Ġa Ġback slash !") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( escaped . raw Ġin Ġspecial Chars ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġescaped . raw ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠRegex Parsing Exception (" Invalid Ġcharacter Ġafter Ġa Ġback slash : Ġ\\ ${ escaped . raw }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnext . raw Ġin Ġspecial Chars Ġ-> Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġreturn Ġnext . raw ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠThis Ġis Ġjust Ġfor Ġsepar ating Ġthe Ġcode Ġfor Ġcharacter Ġclasses Ġfrom Ġthe Ġmain Ġparser Ċ Ġ*/ Ċ private Ġobject ĠChar Classes Ġ{ ĊĠĠĠ Ġprivate Ġval Ġsingle Char Classes : ĠMap < Char , ĠSymbol > Ġ= Ġmap Of ( ĊĠĠĠĠĠĠĠ Ġ' s ' Ġto ĠSymbol . Any Of (" Ġ\ t \ r \ n \ u 0 0 0 B \ u 0 0 0 C "), ĊĠĠĠĠĠĠĠ Ġ' S ' Ġto ĠSymbol . None Of (" Ġ\ t \ r \ n \ u 0 0 0 B \ u 0 0 0 C "), ĊĠĠĠĠĠĠĠ Ġ' d ' Ġto ĠSymbol . Any Of (" 0 1 2 3 4 5 6 7 8 9 "), ĊĠĠĠĠĠĠĠ Ġ' D ' Ġto ĠSymbol . None Of (" 0 1 2 3 4 5 6 7 8 9 "), ĊĠĠĠĠĠĠĠ Ġ' w ' Ġto ĠSymbol . Any Of ((' a ' .. ' z ') Ġ+ Ġ(' A ' .. ' Z ') Ġ+ Ġ(' 0 ' .. ' 9 ') Ġ+ ĠarrayOf ('_ ')), ĊĠĠĠĠĠĠĠ Ġ' W ' Ġto ĠSymbol . None Of ((' a ' .. ' z ') Ġ+ Ġ(' A ' .. ' Z ') Ġ+ Ġ(' 0 ' .. ' 9 ') Ġ+ ĠarrayOf ('_ ')), ĊĠĠĠĠĠĠĠ Ġ' x ' Ġto ĠSymbol . Any Of ((' a ' .. ' f ') Ġ+ Ġ(' A ' .. ' F ') Ġ+ Ġ(' 0 ' .. ' 9 ')), ĊĠĠĠĠĠĠĠ Ġ' O ' Ġto ĠSymbol . Any Of (" 0 1 2 3 4 5 6 7 "), ĊĠĠĠĠĠĠĠ Ġ' n ' Ġto ĠSymbol . Raw Character ('\ n '), ĊĠĠĠĠĠĠĠ Ġ' r ' Ġto ĠSymbol . Raw Character ('\ r '), ĊĠĠĠĠĠĠĠ Ġ' t ' Ġto ĠSymbol . Raw Character ('\ t '), ĊĠĠĠĠĠĠĠ Ġ' v ' Ġto ĠSymbol . Raw Character ('\ u 0 0 0 B '), ĊĠĠĠĠĠĠĠ Ġ' f ' Ġto ĠSymbol . Raw Character ('\ u 0 0 0 C ') ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġfun Ġis Single Char Class ( c : ĠChar ) Ġ= Ġc Ġin Ġsingle Char Classes ĊĠĠĠ Ġfun Ġget Single Char Class ( c : ĠChar ) Ġ= Ġsingle Char Classes [ c ] Ċ } Ċ