import Ġtoken .* Ċ import Ġjava . io . Buffered OutputStream Ċ import Ġjava . io . Data OutputStream Ċ import Ġjava . io . File OutputStream Ċ import Ġkotlin . reflect . jvm . internal . impl . resolve . constants . UInt Value Ċ Ċ class ĠParser Ġ( private Ġval Ġlexer : ĠLex er ) Ġ{ ĊĠĠĠ Ġprivate Ġvar Ġrow Ġ= Ġ 1 ĊĠĠĠ Ġprivate Ġvar Ġcolumn Ġ= Ġ 1 ĊĠĠĠ Ġvar Ġline Ġ= Ġ"" ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġtoken : ĠToken ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġparse ( path : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparser Ġ= ĠParser ( Lexer ("$ path . grp ")) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġinitialize ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparser . row Ġ= Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparser . column Ġ= Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparser . token Ġ= Ġparser . lexer . nextToken () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠWC Printer . print ( path , Ġparser . parse Closure (). to IR (). map ( ir . Instruction :: to WC )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠParsing Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . print () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġparse D ( path : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparser Ġ= ĠParser ( Lexer ("$ path . grp ")) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġinitialize ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparser . row Ġ= Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparser . column Ġ= Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparser . token Ġ= Ġparser . lexer . nextToken () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġast Result Ġ= Ġparser . parse Closure () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln ( ast Result . to S ( 0 )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġir Result Ġ= Ġast Result . to IR () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln ( ir Result ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġwc Result Ġ= Ġir Result . map ( ir . Instruction :: to WC ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠWC Printer . print ( path , Ġwc Result ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠParsing Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . print () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġprivate Ġfun Ġparse Closure (): Ġast . Closure Ġ{ ĊĠĠĠĠĠĠĠ Ġconsume ('{ ') ĊĠĠĠĠĠĠĠ Ġconsume (- 2 ) ĊĠĠĠĠĠĠĠ Ġval Ġstm ts Ġ= ĠArrayList < ast . Statement >() ĊĠĠĠĠĠĠĠ Ġwhile (! match (' } ')) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstmt Ġ= Ġparse Statement () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstm ts . add ( stmt ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġconsume (' }') ĊĠĠĠĠĠĠĠ Ġreturn Ġast . Closure ( stm ts ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġprivate Ġfun Ġparse Statement (): Ġast . Statement Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmatch ( Token . PRINT ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconsume () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstmt Ġ= Ġast . Print ( parse Expression ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( match (- 1 ) Ġ|| Ġmatch (- 2 )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconsume () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstmt ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠParsing Exception ( row , Ġcolumn , Ġline , Ġ" expected Ġ< EOL > Ġor Ġ< EOF >, Ġfound Ġ$ token ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdst Ġ= Ġast . Var Ref ( consume Identifier ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconsume ( Token . ASSIGN ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsrc 1 Ġ= Ġparse Factor () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstmt Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch ('+ ') Ġ-> Ġ{ Ġconsume (); Ġast . Assign ( dst , Ġ"+", Ġsrc 1 , Ġparse Expression ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch ('- ') Ġ-> Ġ{ Ġconsume (); Ġast . Assign ( dst , Ġ"-", Ġsrc 1 , Ġparse Expression ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch ('* ') Ġ-> Ġ{ Ġconsume (); Ġast . Assign ( dst , Ġ"*", Ġsrc 1 , Ġparse Expression ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch ('/') Ġ-> Ġ{ Ġconsume (); Ġast . Assign ( dst , Ġ"/", Ġsrc 1 , Ġparse Expression ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch (' >') Ġ-> Ġ{ Ġconsume (); Ġast . Assign ( dst , Ġ"> ", Ġsrc 1 , Ġparse Expression ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch ( Token . GE ) Ġ-> Ġ{ Ġconsume (); Ġast . Assign ( dst , Ġ"> =", Ġsrc 1 , Ġparse Expression ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch ('< ') Ġ-> Ġ{ Ġconsume (); Ġast . Assign ( dst , Ġ"< ", Ġsrc 1 , Ġparse Expression ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch ( Token . LE ) Ġ-> Ġ{ Ġconsume (); Ġast . Assign ( dst , Ġ"< =", Ġsrc 1 , Ġparse Expression ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch (' =') Ġ-> Ġ{ Ġconsume (); Ġast . Assign ( dst , Ġ"=", Ġsrc 1 , Ġparse Expression ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch ( Token . AND ) Ġ-> Ġ{ Ġconsume (); Ġast . Assign ( dst , Ġ" && ", Ġsrc 1 , Ġparse Expression ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch ( Token . OR ) Ġ-> Ġ{ Ġconsume (); Ġast . Assign ( dst , Ġ" || ", Ġsrc 1 , Ġparse Expression ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠParsing Exception ( row , Ġcolumn , Ġline , Ġ" expected Ġ< EOL > Ġor Ġ< EOF >, Ġfound Ġ$ token ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( match (- 1 ) Ġ|| Ġmatch (- 2 )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconsume () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstmt ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠParsing Exception ( row , Ġcolumn , Ġline , Ġ" expected Ġ< EOL > Ġor Ġ< EOF >, Ġfound Ġ$ token ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġprivate Ġfun Ġparse Expression (): Ġast . Expression Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġleft Ġ= Ġparse Term () ĊĠĠĠĠĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġleft Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch (' >') Ġ-> Ġ{ Ġconsume (); Ġast . Binary Operator ("> ", Ġleft , Ġparse Expression ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch ( Token . GE ) Ġ-> Ġ{ Ġconsume (); Ġast . Binary Operator ("> =", Ġleft , Ġparse Expression ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch ('< ') Ġ-> Ġ{ Ġconsume (); Ġast . Binary Operator ("< ", Ġleft , Ġparse Expression ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch ( Token . LE ) Ġ-> Ġ{ Ġconsume (); Ġast . Binary Operator ("< =", Ġleft , Ġparse Expression ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch (' =') Ġ-> Ġ{ Ġconsume (); Ġast . Binary Operator (" =", Ġleft , Ġparse Expression ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch ( Token . AND ) Ġ-> Ġ{ Ġconsume (); Ġast . Binary Operator (" && ", Ġleft , Ġparse Expression ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch ( Token . OR ) Ġ-> Ġ{ Ġconsume (); Ġast . Binary Operator (" || ", Ġleft , Ġparse Expression ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġreturn Ġleft ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġprivate Ġfun Ġparse Term (): Ġast . Expression Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġleft Ġ= Ġparse Factor () ĊĠĠĠĠĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġleft Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch ('+ ') Ġ-> Ġ{ Ġconsume (); Ġast . Binary Operator ("+ ", Ġleft , Ġparse Term ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch ('- ') Ġ-> Ġ{ Ġconsume (); Ġast . Binary Operator ("- ", Ġleft , Ġparse Term ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch ('* ') Ġ-> Ġ{ Ġconsume (); Ġast . Binary Operator ("* ", Ġleft , Ġparse Term ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch ('/') Ġ-> Ġ{ Ġconsume (); Ġast . Binary Operator ("/", Ġleft , Ġparse Term ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġreturn Ġleft ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġprivate Ġfun Ġparse Factor (): Ġast . Expression Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmatch (' (' ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpr Ġ= Ġparse Expression () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconsume (' )') ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexpr ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmatch ( Token . INTEGER ) Ġ-> Ġast . Integer Literal ( consume Integer ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmatch ( Token . BOOLEAN ) Ġ-> Ġast . Boolean Literal ( consume Boolean ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmatch ( Token . IDENTIFIER ) Ġ-> Ġast . Var Ref ( consume Identifier ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠParsing Exception ( row , Ġcolumn , Ġline , Ġ" expected Ġfactor , Ġfound Ġ$ token ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġprivate Ġfun Ġmatch ( tag : ĠInt ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtoken . tag Ġ== Ġtag ĊĠĠĠ Ġ} ĊĠĠĠ Ġprivate Ġfun Ġmatch ( tag : ĠChar ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġmatch ( tag . toInt ()) ĊĠĠĠ Ġ} ĊĠĠĠ Ġprivate Ġfun Ġconsume () Ġ{ Ġ// ĠTODO ĊĠĠĠĠĠĠĠ Ġrow Ġ= Ġlexer . row ĊĠĠĠĠĠĠĠ Ġcolumn Ġ= Ġlexer . column ĊĠĠĠĠĠĠĠ Ġline Ġ= Ġlexer . line ĊĠĠĠĠĠĠĠ Ġtoken Ġ= Ġlexer . nextToken () ĊĠĠĠ Ġ} ĊĠĠĠ Ġ/** Ġ@ throws ĠClass CastException Ġ{@ code Ġmatch ( token . Token . INTEGER )} Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġconsume Integer (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġvalue Ġ= Ġ( token Ġas ĠInteger Literal ). value ĊĠĠĠĠĠĠĠ Ġconsume () ĊĠĠĠĠĠĠĠ Ġreturn Ġvalue ĊĠĠĠ Ġ} ĊĠĠĠ Ġ/** Ġ@ throws ĠClass CastException Ġ{@ code Ġmatch ( token . Token . BOOLEAN )} Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġconsume Boolean (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġvalue Ġ= Ġ( token Ġas ĠBoolean Literal ). value ĊĠĠĠĠĠĠĠ Ġconsume () ĊĠĠĠĠĠĠĠ Ġreturn Ġvalue ĊĠĠĠ Ġ} ĊĠĠĠ Ġ/** Ġ@ throws ĠClass CastException Ġ{@ code Ġmatch ( token . Token . IDENTIFIER )} Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġconsume Identifier (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġname Ġ= Ġ( token Ġas ĠIdentifier ). name ĊĠĠĠĠĠĠĠ Ġconsume () ĊĠĠĠĠĠĠĠ Ġreturn Ġname ĊĠĠĠ Ġ} ĊĠĠĠ Ġprivate Ġfun Ġconsume ( tag : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmatch ( tag ) Ġ-> Ġconsume () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtag Ġin Ġ 0 x 2 0 .. 0 x 7 f Ġ-> Ġthrow ĠParsing Exception ( row , Ġcolumn , Ġline , Ġ" expected Ġ" Ġ+ Ġtag . to Char () Ġ+ Ġ", Ġfound Ġ$ token ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠParsing Exception ( row , Ġcolumn , Ġline , Ġ" expected Ġ<$ tag >, Ġfound Ġ$ token ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġprivate Ġfun Ġconsume ( tag : ĠChar ) Ġ{ ĊĠĠĠĠĠĠĠ Ġconsume ( tag . toInt ()) ĊĠĠĠ Ġ} Ċ }