package Ġnor swap . aut umn . parsers Ċ import Ġnor swap . aut umn . Grammar Ċ import Ġnor swap . aut umn . Parser Ċ import Ġjava . util . Array Deque Ċ import Ġjava . util . ArrayList Ċ Ċ /** Ċ Ġ* ĠA Ġparser Ġthat Ġmatches Ġapplications Ġof Ġa Ġset Ġof Ġleft - associ ative Ġbinary Ġoperators Ġand Ċ Ġ* Ġpostfix Ġoperators . Ċ Ġ* Ċ Ġ* ĠThis Ġparser Ġmust Ġbe Ġinstantiated Ġthrough Ġthe Ġ[ assoc _ left ] Ġfunction , Ġwhich Ċ Ġ* Ġtakes Ġan Ġinitialization Ġfunction Ġas Ġparameter . Ċ Ġ* Ċ Ġ* ĠWith in Ġthat Ġfunction , Ġyou Ġmust Ġspecify Ġhow Ġto Ġparse Ġthe Ġleft - hand Ġside Ġand Ġright - hand Ġside Ġof Ċ Ġ* Ġthese Ġoperators Ġby Ġassigning Ġthe Ġ[ left ] Ġand Ġ[ right ] Ġproperties . ĠIf Ġboth Ġsides Ġare Ġrecognized Ġby Ċ Ġ* Ġthe Ġsame Ġparser , Ġassign Ġ[ operands ] Ġinstead . ĠFor Ġpostfix Ġoperators , Ġonly Ġthe Ġleft - hand Ġside Ċ Ġ* Ġis Ġrelevant . Ċ Ġ* Ċ Ġ* ĠThe Ġoperators Ġthemselves Ġmust Ġbe Ġdefined Ġwith Ġone Ġof Ġthe Ġ[ op ] Ġor Ġ[ postfix ] Ġfunctions . Ċ Ġ* Ċ Ġ* ĠAll Ġoperators Ġexplicitly Ġhandled Ġby Ġthis Ġparser Ġhave Ġthe Ġsame Ġprecedence , Ġwhich Ġis Ġn atur ally Ċ Ġ* Ġlower Ġthan Ġthat Ġof Ġthe Ġoperators Ġ( if Ġany ) Ġmatched Ġby Ġ[ left ] Ġand Ġ[ right ]. Ċ Ġ* Ċ Ġ* ĠBy Ġdefault , Ġthe Ġparser Ġmatches Ġthe Ġsame Ġthing Ġas Ġits Ġ[ left ] Ġproperty Ġif Ġno Ġbinary Ġor Ġpostfix Ċ Ġ* Ġoperators Ġare Ġmatched . Ġ ĠThis Ġis Ġtypically Ġthe Ġdesired Ġbehaviour Ġwhen Ġimplementing Ġexpressions Ġin Ċ Ġ* Ġa Ġlanguage . ĠThis Ġcan Ġbe Ġcontrolled Ġthrough Ġthe Ġ[ strict ] Ġproperty Ġ( should Ġbe Ġset Ġin Ġthe Ċ Ġ* Ġinitialization Ġfunction ). Ċ Ġ*/ Ċ class ĠAss oc Left Ġinternal Ġconstructor Ġ( val Ġg : ĠGram mar ): ĠParser Ċ { ĊĠĠĠ Ġ// Ġ-------------------------------------------------------------------------------- ------------- ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIf Ġfalse Ġ( default ), Ġthis Ġparser Ġalso Ġmatches Ġthe Ġsame Ġthing Ġas Ġits Ġ[ left ] Ġproperty Ġif Ġno ĊĠĠĠĠ Ġ* Ġbinary Ġor Ġpostfix Ġoperators Ġare Ġmatched . ĠSet Ġthis Ġproperty Ġin Ġthe Ġinitialization Ġfunction . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġvar Ġstrict : ĠBoolean Ġ= Ġfalse ĊĊĠĠĠ Ġ// Ġ-------------------------------------------------------------------------------- ------------- ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġparser Ġused Ġto Ġmatch Ġthe Ġleft - hand Ġside Ġof Ġthe Ġoperators . ĊĠĠĠĠ Ġ* ĠMust Ġbe Ġset Ġ( or Ġ[ operands ]) Ġin Ġ[ assoc _ left ]' s Ġinitialization Ġfunction . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġvar Ġleft : ĠParser ? Ġ= Ġnull ĊĊĠĠĠ Ġ// Ġ-------------------------------------------------------------------------------- ------------- ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġparser Ġused Ġto Ġmatch Ġthe Ġright - hand Ġside Ġof Ġthe Ġoperators . ĊĠĠĠĠ Ġ* ĠMust Ġbe Ġset Ġ( or Ġ[ operands ]) Ġ[ assoc _ left ]' s Ġinitialization Ġfunction . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġvar Ġright : ĠParser ? Ġ= Ġnull ĊĊĠĠĠ Ġ// Ġ-------------------------------------------------------------------------------- ------------- ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġparser Ġused Ġto Ġmatch Ġboth Ġsides Ġof Ġthe Ġoperator . ĊĠĠĠĠ Ġ* ĠSetting Ġthis Ġproperty Ġautomatically Ġsets Ġboth Ġ[ left ] Ġand Ġ[ right ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġvar Ġoperands : ĠParser ? ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( left Ġ!= Ġright ) Ġthrow ĠIllegalStateException (" Left Ġand Ġright Ġoperands Ġare Ġdifferent .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġleft ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġset Ġ( p ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġleft Ġ Ġ= Ġp ĊĠĠĠĠĠĠĠĠĠĠĠ Ġright Ġ= Ġp ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġ-------------------------------------------------------------------------------- ------------- ĊĊĠĠĠ Ġ/** ĠMat ches Ġthe Ġoperator Ġ+ Ġthe Ġright - hand Ġside . Ġ*/ ĊĠĠĠ Ġ@ Published Api ĊĠĠĠ Ġinternal Ġval Ġoperators Ġ= ĠArrayList < Parser >() ĊĊĠĠĠ Ġ/** ĠStack Ġframe Ġwhen Ġthe Ġparser Ġwas Ġinvoked . Ġ*/ ĊĠĠĠ Ġ@ Published Api ĊĠĠĠ Ġinternal Ġvar Ġframe Ġ= Ġ 0 ĊĊĠĠĠ Ġ/** ĠPrevious Ġvalues Ġof Ġ[ frame ] Ġ( to Ġsupport Ġrecursive Ġinvocation Ġof ĠAss oc Left ). Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġframes Ġ= ĠArray Deque < Int >() ĊĊĠĠĠ Ġ// Ġ-------------------------------------------------------------------------------- ------------- ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAdds Ġa Ġbinary Ġoperator Ġwith Ġthe Ġgiven Ġ[ syntax ] Ġ( operator Ġonly ) Ġand Ġthe Ġgiven Ġ[ effect ] Ġwhen ĊĠĠĠĠ Ġ* Ġthe Ġoperator Ġis Ġmatched Ġwith Ġits Ġoperands . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinline Ġfun Ġop _ stack less Ġ( ĊĠĠĠĠĠĠĠ Ġcross inline Ġsyntax : ĠParser , ĊĠĠĠĠĠĠĠ Ġcross inline Ġeffect : ĠGram mar . () Ġ-> ĠUnit ) ĊĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġoperators Ġ+= Ġ{ Ġg . seq Ġ{ Ġsyntax () Ġ&& Ġright !! () Ġ&& Ġg . perform Ġ{ Ġeffect () Ġ} Ġ} Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġ-------------------------------------------------------------------------------- ------------- ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAdds Ġa Ġbinary Ġoperator Ġwith Ġthe Ġgiven Ġ[ syntax ] Ġ( operator Ġonly ) Ġand Ġthe Ġgiven Ġ[ effect ] Ġwhen ĊĠĠĠĠ Ġ* Ġthe Ġoperator Ġis Ġmatched Ġwith Ġits Ġoperands . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThe Ġ[ effect ] Ġfunction Ġis Ġpassed Ġthe Ġstack Ġframe Ġof Ġthe Ġoperator Ġand Ġits Ġoperands . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinline Ġfun Ġop _ a ffect Ġ( ĊĠĠĠĠĠĠĠ Ġcross inline Ġsyntax : ĠParser , ĊĠĠĠĠĠĠĠ Ġcross inline Ġeffect : ĠGram mar .( Array < Any ?> ) Ġ-> ĠUnit ) ĊĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġop _ stack less ( syntax ) Ġ{ Ġeffect ( frame _ end ( frame )) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġ-------------------------------------------------------------------------------- ------------- ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAdds Ġa Ġbinary Ġoperator Ġwith Ġthe Ġgiven Ġ[ syntax ] Ġ( operator Ġonly ) Ġand Ġthe Ġgiven Ġ[ effect ] Ġwhen ĊĠĠĠĠ Ġ* Ġthe Ġoperator Ġis Ġmatched Ġwith Ġits Ġoperands . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThe Ġ[ effect ] Ġfunction Ġis Ġpassed Ġthe Ġstack Ġframe Ġof Ġthe Ġoperator Ġand Ġits Ġoperands , ĊĠĠĠĠ Ġ* Ġand Ġits Ġresult Ġis Ġpushed Ġon Ġthe Ġvalue Ġstack . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinline Ġfun Ġop Ġ( ĊĠĠĠĠĠĠĠ Ġcross inline Ġsyntax : ĠParser , ĊĠĠĠĠĠĠĠ Ġcross inline Ġeffect : ĠGram mar .( Array < Any ?> ) Ġ-> ĠAny ?) ĊĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġop _ a ffect ( syntax ) Ġ{ Ġstack . push ( effect ( it )) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġ-------------------------------------------------------------------------------- ------------- ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAdds Ġa Ġpostfix Ġoperator Ġ( no Ġright Ġoperand ) Ġwith Ġthe Ġgiven Ġ[ syntax ] Ġ( operator Ġonly ) Ġand Ġthe ĊĠĠĠĠ Ġ* Ġgiven Ġ[ effect ] Ġwhen Ġthe Ġoperator Ġis Ġmatched Ġwith Ġits Ġoperand . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinline Ġfun Ġpostfix _ stack less ( ĊĠĠĠĠĠĠĠ Ġcross inline Ġsyntax : ĠParser , ĊĠĠĠĠĠĠĠ Ġcross inline Ġeffect : ĠGram mar . () Ġ-> ĠUnit ) ĊĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġoperators Ġ+= Ġ{ Ġg . seq Ġ{ Ġsyntax () Ġ&& Ġg . perform Ġ{ Ġeffect () Ġ} Ġ} Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġ-------------------------------------------------------------------------------- ------------- ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAdds Ġa Ġpostfix Ġoperator Ġ( no Ġright Ġoperand ) Ġwith Ġthe Ġgiven Ġ[ syntax ] Ġ( operator Ġonly ) Ġand Ġthe ĊĠĠĠĠ Ġ* Ġgiven Ġ[ effect ] Ġwhen Ġthe Ġoperator Ġis Ġmatched Ġwith Ġits Ġoperand . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThe Ġ[ effect ] Ġfunction Ġis Ġpassed Ġthe Ġstack Ġframe Ġof Ġthe Ġoperator Ġand Ġits Ġoperand . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinline Ġfun Ġpostfix _ a ffect ( ĊĠĠĠĠĠĠĠ Ġcross inline Ġsyntax : ĠParser , ĊĠĠĠĠĠĠĠ Ġcross inline Ġeffect : ĠGram mar .( Array < Any ?> ) Ġ-> ĠUnit ) ĊĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġpostfix _ stack less ( syntax ) Ġ{ Ġeffect ( frame _ end ( frame )) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġ-------------------------------------------------------------------------------- ------------- ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAdds Ġa Ġpostfix Ġoperator Ġ( no Ġright Ġoperand ) Ġwith Ġthe Ġgiven Ġ[ syntax ] Ġ( operator Ġonly ) Ġand Ġthe ĊĠĠĠĠ Ġ* Ġgiven Ġ[ effect ] Ġwhen Ġthe Ġoperator Ġis Ġmatched Ġwith Ġits Ġoperand . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThe Ġ[ effect ] Ġfunction Ġis Ġpassed Ġthe Ġstack Ġframe Ġof Ġthe Ġoperator Ġand Ġits Ġoperand , ĊĠĠĠĠ Ġ* Ġand Ġits Ġresult Ġis Ġpushed Ġon Ġthe Ġvalue Ġstack . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinline Ġfun Ġpostfix ( ĊĠĠĠĠĠĠĠ Ġcross inline Ġsyntax : ĠParser , ĊĠĠĠĠĠĠĠ Ġcross inline Ġeffect : ĠGram mar .( Array < Any ?> ) Ġ-> ĠAny ?) ĊĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġpostfix _ a ffect ( syntax ) Ġ{ Ġstack . push ( effect ( it )) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġ-------------------------------------------------------------------------------- ------------- ĊĊĠĠĠ Ġprivate Ġfun Ġinvoke _ strict (): ĠBoolean ĊĠĠĠĠĠĠĠ Ġ= Ġg . seq Ġ{ Ġleft !! () Ġ&& Ġg . repeat 1 Ġ{ Ġoperators . any Ġ{ Ġit () Ġ} Ġ} Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġinvoke _ l ax (): ĠBoolean ĊĠĠĠĠĠĠĠ Ġ= Ġg . seq Ġ{ Ġleft !! () Ġ&& Ġg . repeat 0 Ġ{ Ġoperators . any Ġ{ Ġit () Ġ} Ġ} Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġinvoke (): ĠBoolean ĊĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġframes . push ( frame ) ĊĠĠĠĠĠĠĠ Ġframe Ġ= Ġg . frame _ start () ĊĊĠĠĠĠĠĠĠ Ġval Ġout Ġ= ĠĠ Ġif Ġ( strict ) Ġinvoke _ strict () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĠĠĠĠĠĠĠ Ġinvoke _ l ax () ĊĊĠĠĠĠĠĠĠ Ġframe Ġ= Ġframes . pop () ĊĠĠĠĠĠĠĠ Ġreturn Ġout ĊĠĠĠ Ġ} Ċ } Ċ Ċ // Ġ================================================================= ================================ Ċ Ċ /** Ċ Ġ* ĠConstructor Ġfor Ġ[ Assoc Left ]. ĠSee Ġthe Ġclass Ġdocumentation Ġfor Ġdetails , Ġnot ably Ċ Ġ* Ġon Ġthe Ġcontent Ġof Ġ[ init ]. Ċ Ġ*/ Ċ fun ĠGram mar . assoc _ left Ġ( init : ĠAss oc Left . () Ġ-> ĠUnit ): ĠParser Ċ { ĊĠĠĠ Ġval Ġout Ġ= ĠAss oc Left ( this ) ĊĠĠĠ Ġout . init () ĊĠĠĠ Ġif Ġ( out . left Ġ== Ġnull Ġ|| Ġout . right Ġ== Ġnull ) ĊĠĠĠĠĠĠĠ Ġthrow ĠError Ġ(" You Ġdid Ġnot Ġdefine Ġa Ġhigher - pre cedence Ġparser Ġfor Ġa Ġbinary Ġoperator .") ĊĠĠĠ Ġreturn Ġout Ċ } Ċ