1

I'm trying to build a basic combinator parser in Scala and when trying to compile the most basic parser with it (the parser of the letter 'A') I get three syntax errors from scalac which I don't understand. I'm looking at my code and can't figure out which parts of the syntax are incorrect, even when comparing with examples online. Could someone please explain what parts of my Scala code are wrong here?

Code:

import lexer
import scala.Option

object Main {
  def main(args: Array[String]) {
    val Lexer = new lexer.Lexer
    val tokens = Lexer.lex(args(0))
    val parseA = satsify(t => t.key == "A")
    println(parseA(tokens))
  }

  def satsify(predicate: Token => Bool): List(Token) => Option[(Token, List(Token))] = {
    tl: List(Token) => match tl { 
        case tl.isEmpty => None 
        case predicate(tl(0)) => Some(tl(0), tl.tail)
        case _ => None
    }
  }
}

Errors:

combParser.scala:2: error: '.' expected but ';' found.
import scala.Option
^
combParser.scala:12: error: '=' expected but '(' found.
  def satsify(predicate: Token => Bool): List(Token) => Option[(Token, List(Token))] = {
                                             ^
combParser.scala:19: error: illegal start of simple expression
}
^
three errors found

1 Answer 1

2

There are quite a few syntax errors, mainly

  • type constructor takes a type parameters using square brackets, thus List[Token] instead of List(Token)
  • guards inside pattern matching cannot be used directly, thus case v if predicate(tl(0)) => instead of case predicate(tl(0)) =>

Taking above into account try

  def satsify(predicate: Token => Boolean): List[Token] => Option[(Token, List[Token])] = {
    (tl: List[Token]) => tl match {
      case Nil => None
      case head :: tail if predicate(head) => Some(head, tail)
      case _ => None
    }
  }
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, this solved my errors and seems like a much cleaner way to write the code. Could you explain how the second case in the pattern match works though? How can you create these head and tail variables directly and have them correspond to the correct parts of the list? Also, the first error given by scalac still persists. Do you have an idea what causes this? Thanks.
Scala has Semicolon Inference, which allows you to leave out semicolons and the compiler will infer them for you. In this case, it has inferred a semicolon between the two import statements, i.e. what the compiler sees is import lexer; import scala.Option. The syntax for an import statement is import <path where to find the import>.<what to import>. You are missing the "what to import" bit, so Scala is expecting a . but is instead finding the ; it inserted itself. Also note there is an implicit import scala._ in every Scala program, so your second import doesn't do anything.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.