Skip to content

Commit

Permalink
Handles cases where non-numbers (unparseable inputs) are passed to Wo…
Browse files Browse the repository at this point in the history
…rdsToNumber.
  • Loading branch information
bethard committed Aug 9, 2019
1 parent d09f2ed commit 108116b
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 6 deletions.
14 changes: 8 additions & 6 deletions src/main/scala/org/clulab/timenorm/scate/WordsToNumber.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import org.apache.commons.io.IOUtils
import org.clulab.timenorm.scfg.SynchronousParser.Tree
import org.clulab.timenorm.scfg.{SynchronousGrammar, SynchronousParser}

import scala.util.{Failure, Success}


object WordsToNumber {
def apply(languageCode: String): WordsToNumber = languageCode match {
Expand All @@ -16,14 +18,14 @@ object WordsToNumber {

class WordsToNumber(grammarStream: InputStream) extends Function[Array[String], Option[Long]] {

private val grammar = SynchronousGrammar.fromString(IOUtils.toString(grammarStream, Charset.forName("ascii")))
private val sourceWords = grammar.sourceSymbols()
private val parser = new SynchronousParser(grammar)
private val parser = new SynchronousParser(SynchronousGrammar.fromString(
IOUtils.toString(grammarStream, Charset.forName("ascii"))))

override def apply(words: Array[String]): Option[Long] = {
if (!words.forall(sourceWords)) None else parser.parseAll(words) match {
case Array(tree) => Some(this.toDigits(tree).foldLeft(0L) { case (sum, digit) => 10L * sum + digit })
case trees => throw new UnsupportedOperationException(
parser.tryParseAll(words.toIndexedSeq) match {
case Failure(_) => None
case Success(IndexedSeq(tree)) => Some(this.toDigits(tree).foldLeft(0L) { case (sum, digit) => 10L * sum + digit })
case Success(trees) => throw new UnsupportedOperationException(
s"Ambiguous grammar for ${words.toList}. Parses:\n${trees.mkString("\n")}")
}
}
Expand Down
11 changes: 11 additions & 0 deletions src/main/scala/org/clulab/timenorm/scfg/SynchronousParser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.clulab.timenorm.scfg
import scala.collection.immutable.IndexedSeq
import scala.collection.mutable
import scala.collection.mutable.ListBuffer
import scala.util.{Try, control}

/**
* A parser for synchronous grammars.
Expand Down Expand Up @@ -54,6 +55,16 @@ class SynchronousParser(grammar: SynchronousGrammar) {
trees
}

/**
* Attempt to parse the source tokens into a tree of non-terminals and target tokens.
*
* @param sourceTokens The source tokens to be parsed.
* @return Success(trees) if the source tokens could be parsed, Failure otherwise.
*/
def tryParseAll(sourceTokens: IndexedSeq[String]): Try[IndexedSeq[Tree.NonTerminal]] = {
control.Exception.catching(classOf[UnsupportedOperationException]).withTry(parseAll(sourceTokens))
}

private def parseChart(sourceTokens: IndexedSeq[String]): Array[Array[ChartEntry]] = {
val nTokens = sourceTokens.size
val chart = Array.tabulate(nTokens + 1, nTokens) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,7 @@ class WordsToNumberTest extends FunSuite with TypesSuite {

test("English invalid numbers") {
assert(enTextToNumber(Array("several")) === None)
assert(enTextToNumber(Array("and")) === None)
assert(enTextToNumber(Array.empty) === None)
}
}

0 comments on commit 108116b

Please sign in to comment.