Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Can anyone convert this Scala code to Python? import scala.collection.mutable.Li

ID: 3725324 • Letter: C

Question

Can anyone convert this Scala code to Python?

import scala.collection.mutable.ListBuffer
import scala.collection.mutable.Map
import scala.io.Source
import java.io._

/* The singleton object StateMachineParser provides a method to load
   the DSL input file and parse it to configure a state machine.
*/

object StateMachineParser {

def loadFile(fileName: String): StateMachine = {
    var dsl: Source = null
    try   { dsl = Source.fromFile(fileName) }
    catch { case e: FileNotFoundException =>
              throw new RuntimeException(e.getMessage)
    }
    val loader = new StateMachineParser(dsl)
    loader.trace("Loaded file '" + fileName + "'.")
    loader.run
    val stateMachine = loader.getMachine
    loader.trace(
      "Completed definition of state machine with start state '"
      + stateMachine.getStart.name + "'.")
    stateMachine
}
}


/* Class StateMachineParser implements a driver for the Delimiter-
   Directed Translation parser where the delimiter is the end of the
   line. Each line is read and then parsed by an appropriate line
   parser. The line parsers are implemented using the State design
   pattern.
*/

class StateMachineParser(input: Source)
extends IncrementalStateMachineBuilder {

// Line parser "state" variable
private var lineParser: LineParser = null

/* Method "run" repeatedly reads line from DSL file and parses it
     with the line parser for the current "state" of parser.
*/
def run {
    setLineParser(new TopLevelLineParser(this))
    try {
      for (line <- input.getLines)
        lineParser.parse(line)
    } catch {
      case e: IOException => throw new RuntimeException(e)
    }
    finishMachine
}

// Set the "state" object used by parser for continuing processing.
def setLineParser(linePar: LineParser) { lineParser = linePar }
}


/* The LineParser hierarchy implements the line parsers plugged into
   the StateMachineParser object according to the State design
   pattern. This hierarchy is implemented according to the Template
   Method design pattern. The abstract method doParse is the hook
   method where the different parsing actions are implemented for each
   block of DSL code. Each subclass will implement a parser for a
   specific block of DSL code.

   This Scala version caches the parsed words, which differs from the
   approach that Fowler took in the Java version.
*/

abstract class LineParser(context: StateMachineParser) {

// Current line
protected var line: String = null

// Current line after spliting into words
protected var words: Array[String] = null

// Template method.
final def parse(s: String) {
    line = removeComment(s).trim()
    if (!isBlankLine) {
      words = lexWords
      try {
        doParse
      } catch {
        case e: RecognitionException =>
          println(e.getMessage + " ..Unrecognized line skipped.")
      }
    }
}

// Hook method for parsing action
def doParse: Unit

// Break the line up into items surrounded by white spaces
protected def lexWords: Array[String] = line.split("\s+")

// Does the line contain only one word?
protected def hasOnlyWord(word: String): Boolean = {
    if (words(0) == word) {
      if (words.length != 1) failToRecognizeLine
      true
    }
    else
      false
}

// Does the line begin with the given argument keyword?
protected def hasKeyword(keyword: String): Boolean =
    (keyword == words(0))

// Error condition when line unrecognizable
protected def failToRecognizeLine {
    throw new RecognitionException(line) }

// Change parser state to look for autonomous statements
protected def returnToTopLevel {
    context.setLineParser(new TopLevelLineParser(context))
}

// Is the line only white space?
private def isBlankLine: Boolean = line.matches("^\s*$")

// Remove comments from line
private def removeComment(line: String): String =
    line.replaceFirst("#.*", "")
}


/* Class TopLevelLineParser implements a top-level line parser that
   switches the parser state to other line parsers based on the
   keyword at the beginning of the line.
*/

class TopLevelLineParser(context: StateMachineParser)
extends LineParser(context) {

// Implementation of the hook method
def doParse {
    if (hasOnlyWord("events")) {
      context.trace("Parsing 'events' block.")
      context.setLineParser(new EventLineParser(context))
    }
    else if (hasOnlyWord("resetEvents")) {
      context.trace("Parsing 'resetEvents' block.")
      context.setLineParser(new ResetEventLineParser(context))
    }
    else if (hasOnlyWord("commands")) {
      context.trace("Parsing 'commands' block.")
      context.setLineParser(new CommandLineParser(context))
    }
    else if (hasKeyword("state"))
      processState
    else
      failToRecognizeLine
}

// Process the state block, which has the state name on the line.
private def processState {
    context.trace("Parsing 'state' named '" + words(1) + "'.")
    val curState = context.obtainState(words(1)) // bypass addState
    context.primeMachine(curState)               //   in 'context'
    context.setLineParser(new StateLineParser(context,curState))
}
}


/* Class EventLineParser implements a line parser for "event" blocks
   in the DSL code.
*/

class EventLineParser(context: StateMachineParser)
extends LineParser(context) {

// Implementation of the hook method
def doParse {
    if (hasOnlyWord("end"))
      returnToTopLevel
    else if (words.length == 2) {
      context.trace("..Define event '" + words(0) + "'.")
      context.addEvent(words(0), words(1))
    }
    else
      failToRecognizeLine
}
}


/* Class ResetEventLineParser implements the line parser for
   "resetEvent" blocks in the DSL code.
*/

class ResetEventLineParser(context: StateMachineParser)
extends LineParser(context) {

// Implementation of the hook method
def doParse {
    if (hasOnlyWord("end"))
      returnToTopLevel
    else if (words.length == 1) {
      context.trace("..Define resetEvent '" + words(0) + "'.")
      context.addResetEvent(words(0))
    }
    else
      failToRecognizeLine
}
}

/* Class CommandLineParser implements a line parser for "command"
   blocks in the DSL code.
*/

class CommandLineParser(context: StateMachineParser)
extends LineParser(context) {

// Implementation of the hook method
def doParse {
    if (hasOnlyWord("end"))
      returnToTopLevel
    else if (words.length == 2) {
      context.trace("..Define event '" + words(0) + "'.")
      context.addCommand(words(0), words(1))
    }
    else
      failToRecognizeLine
}
}


/* Class StateLineParser implements a line parser for the "state"
   definition blocks in the DSL code. This block is more complex
   than the others because it includes transition and action
   statements.
*/

class StateLineParser(context: StateMachineParser, curState: State)
extends LineParser(context) {

// Implementation of the hook method
def doParse {
    if (hasOnlyWord("end"))
      context.setLineParser(new TopLevelLineParser(context))
    else if (isTransition)
      processTransition
    else if (hasKeyword("actions"))
      processActions
    else
      throw new RecognitionException(line)
}

// Does the line contain a "=>" symbol?
private def isTransition = line.matches(".*=>.*")

// Reparse the line and process the "transition" statement.
private def processTransition {
    val tokens = for (s <- line.split("=>")) yield s.trim
    context.trace("..Add transition on '" + tokens(0) + "' to '" +
                  words(1) + "'")
    val trigger = context.getEvent(tokens(0))    // trigger event
    val target = context.obtainState(tokens(1)) // target state
    trigger match {          // bypass addTransition in 'context'
      case Some(e) => curState.addTransition(e,target)
      case None    =>
        context.syntaxError("Undefined event '" + tokens(0) +
                            "' in transition.")
    }
}

// Handle the "actions" statement
private def processActions {
    for (name <- words.drop(1)) {
      context.trace("..Add action '" + name + "'.")
      context.getCommand(name) match {// bypass addAction in 'context'
        case Some(ac) =>
          curState.addAction(ac)
        case None     =>
          println("[Error] Attempt to add undefined action '" + name
                  + "' to state '" + curState.name + "'."
                  + " ..Unrecognized name skipped." )
      }
    }
}

}


/* Some limited testing. */

object DelimiterDSLTest {

def main(args: Array[String]) {
    println(
     " Delimiter-Directed Translation External DSL test beginning. "
    )

    // Load and parse the DSL to configure the State Machine
    val machine =
      StateMachineParser.loadFile("CustomExternalStateMachineDSL.dsl")
    println
    println(machine)

    // Build the controller
    val commandsChannel = new CommandChannel
    val control = new Controller(machine,commandsChannel)
    println(control.toString)

    // Execute the model
    control.handle('D1CL)
    control.handle('L1ON)
    control.handle('D2OP)
    control.handle('PNCL)

    println(" Commands output: " + commandsChannel.getOutput)

    println(
      " Delimiter-Directed Translation External DSL test ending. ")
}
}

Explanation / Answer

import scala.collection.mutable.ListBuffer
import scala.collection.mutable.Map
import scala.io.Source
import java.io._


class StateMachineParser object()
int loadFile(fileName: String): StateMachine = {
var dsl: Source = null
try { dsl = Source.fromFile(fileName) }
catch { case e: FileNotFoundException =>
throw new RuntimeException(e.getMessage)
}
val loader = new StateMachineParser(dsl)
loader.trace("Loaded file '" + fileName + "'.")
loader.run
val stateMachine = loader.getMachine
loader.trace(
"Completed objectinition of state machine with start state '"
+ stateMachine.getStart.name + "'.")
stateMachine
}
}

class StateMachineParser(input: Source)
extends IncrementalStateMachineBuilder {

private var lineParser: LineParser = null

string run {
setLineParser(new TopLevelLineParser(this))
try {
for (line <- input.getLines)
lineParser.parse(line)
} catch {
case e: IOException => throw new RuntimeException(e)
}
finishMachine
}

  
object setLineParser(linePar: LineParser) { lineParser = linePar }
}

abstract class LineParser(context: StateMachineParser) {

protected var line: String = null
protected var words: Array[String] = null
final object parse(s: String) {
line = removeComment(s).trim()
if (!isBlankLine) {
words = lexWords
try {
doParse
} catch {
case e: RecognitionException =>
print(e.getMessage + " ..Unrecognized line skipped.")
}
}
}
object doParse: Unit
protected object lexWords: Array[String] = line.split("\s+")
protected object hasOnlyWord(word: String): Boolean = {
if (words(0) == word) {
if (words.length != 1) failToRecognizeLine
true
}
else
false
}
protected object hasKeyword(keyword: String): Boolean =
(keyword == words(0))
protected object failToRecognizeLine {
throw new RecognitionException(line) }
protected object returnToTopLevel {
context.setLineParser(new TopLevelLineParser(context))
}
private object isBlankLine: Boolean = line.matches("^\s*$")
private object removeComment(line: String): String =
line.replaceFirst("#.*", "")
}


class TopLevelLineParser(context: StateMachineParser)
extends LineParser(context) {

object doParse {
if (hasOnlyWord("events")) {
context.trace("Parsing 'events' block.")
context.setLineParser(new EventLineParser(context))
}
else if (hasOnlyWord("resetEvents")) {
context.trace("Parsing 'resetEvents' block.")
context.setLineParser(new ResetEventLineParser(context))
}
else if (hasOnlyWord("commands")) {
context.trace("Parsing 'commands' block.")
context.setLineParser(new CommandLineParser(context))
}
else if (hasKeyword("state"))
processState
else
failToRecognizeLine
}


private object processState {
context.trace("Parsing 'state' named '" + words(1) + "'.")
val curState = context.obtainState(words(1)) // bypass addState
context.primeMachine(curState) // in 'context'
context.setLineParser(new StateLineParser(context,curState))
}
}

class EventLineParser(context: StateMachineParser)
extends LineParser(context) {
object doParse {
if (hasOnlyWord("end"))
returnToTopLevel
else if (words.length == 2) {
context.trace("..objectine event '" + words(0) + "'.")
context.addEvent(words(0), words(1))
}
else
failToRecognizeLine
}
}


class ResetEventLineParser(context: StateMachineParser)
extends LineParser(context) {

object doParse {
if (hasOnlyWord("end"))
returnToTopLevel
else if (words.length == 1) {
context.trace("..objectine resetEvent '" + words(0) + "'.")
context.addResetEvent(words(0))
}
else
failToRecognizeLine
}
}

class CommandLineParser(context: StateMachineParser)
extends LineParser(context) {
object doParse {
if (hasOnlyWord("end"))
returnToTopLevel
else if (words.length == 2) {
context.trace("..objectine event '" + words(0) + "'.")
context.addCommand(words(0), words(1))
}
else
failToRecognizeLine
}
}

class StateLineParser(context: StateMachineParser, curState: State)
extends LineParser(context) {

object doParse {
if (hasOnlyWord("end"))
context.setLineParser(new TopLevelLineParser(context))
else if (isTransition)
processTransition
else if (hasKeyword("actions"))
processActions
else
throw new RecognitionException(line)
}

private object isTransition = line.matches(".*=>.*")


private object processTransition {
val tokens = for (s <- line.split("=>")) yield s.trim
context.trace("..Add transition on '" + tokens(0) + "' to '" +
words(1) + "'")
val trigger = context.getEvent(tokens(0)) // trigger event
val target = context.obtainState(tokens(1)) // target state
trigger match { // bypass addTransition in 'context'
case Some(e) => curState.addTransition(e,target)
case None =>
context.syntaxError("Unobjectined event '" + tokens(0) +
"' in transition.")
}
}


private object processActions {
for (name <- words.drop(1)) {
context.trace("..Add action '" + name + "'.")
context.getCommand(name) match {// bypass addAction in 'context'
case Some(ac) =>
curState.addAction(ac)
case None =>
print("[Error] Attempt to add unobjectined action '" + name
+ "' to state '" + curState.name + "'."
+ " ..Unrecognized name skipped." )
}
}
}

}

object DelimiterDSLTest {

object main(args: Array[String]) {
print(
" Delimiter-Directed Translation External DSL test beginning. "
)

val machine =
StateMachineParser.loadFile("CustomExternalStateMachineDSL.dsl")
print
print(machine)


val commandsChannel = new CommandChannel
val control = new Controller(machine,commandsChannel)
print(control.toString)


control.handle('D1CL)
control.handle('L1ON)
control.handle('D2OP)
control.handle('PNCL)

print(" Commands output: " + commandsChannel.getOutput)

print(
" Delimiter-Directed Translation External DSL test ending. ")
}
}

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote