Guest User

Untitled

a guest
Nov 22nd, 2018
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.72 KB | None | 0 0
  1. import scala.util.parsing.combinator.Parsers
  2. import scala.util.parsing.combinator.JavaTokenParsers
  3.  
  4. object Main
  5. {
  6. def main(args: Array[String])
  7. {
  8. val arg = "( x + 0 ) - ( 1 * --x )"
  9.  
  10. TP2.parseAll( TP2.expression, arg ) match {
  11. case TP2.Success( ast, _ ) => {
  12. println( ast )
  13. println( PostfixPrinter( ast ) )
  14. println( new Evaluator( Map( "x" -> 2 ) )( ast ) )
  15. println( Simplifier( ast ) )
  16. }
  17. case TP2.NoSuccess( msg, _ ) => println( msg )
  18. }
  19. }
  20. }
  21.  
  22. sealed abstract class Expression
  23. case class Variable( label: String ) extends Expression
  24. case class Number( num: Int ) extends Expression
  25. case class UnaryOperator( operator: String, arg: Expression ) extends Expression
  26. case class BinaryOperator( operator: String, left: Expression, right: Expression ) extends Expression
  27.  
  28. object PostfixPrinter
  29. {
  30. def apply( e: Expression ): String =
  31. {
  32. e match {
  33. case Variable( label ) => label
  34. case Number( num ) => num.toString
  35. case UnaryOperator( operator, expression ) => apply( expression ) + operator
  36. case BinaryOperator( operator, left, right ) => apply( left ) + apply( right ) + operator
  37. }
  38. }
  39. }
  40.  
  41. class Evaluator( idTable: Map[String, Int] )
  42. {
  43. def apply( e: Expression ): Int =
  44. {
  45. e match {
  46. case Variable( label ) => idTable.get( label ) match {
  47. case Some( value ) => value
  48. case None => error( label + " is not defined" )
  49. }
  50. case Number( num ) => num
  51. case UnaryOperator( "-", expression ) => - apply( expression )
  52. case BinaryOperator( "+", left, right ) => apply( left ) + apply( right )
  53. case BinaryOperator( "-", left, right ) => apply( left ) - apply( right )
  54. case BinaryOperator( "*", left, right ) => apply( left ) * apply( right )
  55. case BinaryOperator( "/", left, right ) => apply( left ) / apply( right )
  56. }
  57. }
  58. }
  59.  
  60. object Simplifier
  61. {
  62. def apply( expression: Expression ): Expression =
  63. {
  64. case class NilExpression extends Expression
  65. def fixedPoint( current: Expression, last: Expression ): Expression = {
  66.  
  67. def reduce( e: Expression ): Expression = e match {
  68.  
  69. // Same subtraction
  70. case BinaryOperator( "-", x, y ) if x == y => Number( 0 )
  71.  
  72. // Adding zero
  73. case BinaryOperator( "+", x, Number( 0 ) ) => x
  74. case BinaryOperator( "+", Number( 0 ), y ) => y
  75.  
  76. // Multiplying by one
  77. case BinaryOperator( "*", x, Number( 1 ) ) => x
  78. case BinaryOperator( "*", Number( 1 ), y ) => y
  79.  
  80. // Double negation
  81. case UnaryOperator( "-", UnaryOperator( "-", x ) ) => x
  82.  
  83. // Recursive decent
  84. case BinaryOperator( op, x, y ) => BinaryOperator( op, apply( x ), apply( y ) )
  85. case UnaryOperator( op, x ) => UnaryOperator( op, apply( x ) )
  86.  
  87. // Leaves
  88. case x: Number => x
  89. case x: Variable => x
  90. }
  91.  
  92. if( current == last ) current
  93. else fixedPoint( reduce( current ), current )
  94. }
  95.  
  96. fixedPoint( expression, NilExpression() )
  97. }
  98. }
  99.  
  100. object TP2 extends JavaTokenParsers
  101. {
  102. def expression: Parser[Expression] = addExpression
  103.  
  104. def addExpression: Parser[Expression] =
  105. {
  106. multiplicationExpression ~ ( ( ( "+" | "-" ) ~ multiplicationExpression )* ) ^^ mkBinary
  107. }
  108.  
  109. def multiplicationExpression: Parser[Expression] =
  110. {
  111. unaryExpression ~ ( ( ( "*" | "/" ) ~ unaryExpression )* ) ^^ mkBinary
  112. }
  113.  
  114. def unaryExpression: Parser[Expression] =
  115. {
  116. rep( "-" ) ~ basicExpression ^^ {
  117. case Nil ~ e => e
  118. case l ~ e => ( l :\ e ){ (a, b) => UnaryOperator( a, b ) }
  119. }
  120. }
  121.  
  122. def basicExpression: Parser[ Expression ] =
  123. (
  124. ident ^^ ( id => new Variable( id ) )
  125. | wholeNumber ^^ ( n => new Number( n.toInt ) )
  126. | "(" ~> expression <~ ")" ^^ ( e => e )
  127. )
  128.  
  129. def mkBinary: Expression ~ List[ String ~ Expression ] => Expression = {
  130. case left ~ rest => ( left /: rest ) {
  131. case ( l, op ~ r ) => BinaryOperator( op, l, r )
  132. }
  133. }
  134. }
Add Comment
Please, Sign In to add comment