2016-08-05 43 views
1

我正在嘗試編寫一個與Milner的CCS非常相似的語言的解析器。基本上,我解析到目前爲止有以下幾種形式的表現:SCALA:如何將一個Parser Combinator結果轉換爲Scala List [String]?

  • aba1
  • A.0

的表達必須以字母開頭(不含T),並可能有任意數量的第一個字母后面的字母(用'。'分隔)。表達式必須以數字結尾(爲了簡單起見,我現在選擇0到2之間的數字)。我想使用Parser Combinators for Scala,但這是我第一次與他們合作。這是我到目前爲止有:

import scala.util.parsing.combinator._ 

class SimpleParser extends RegexParsers { 
    def alpha: Parser[String] = """[^t]{1}""".r ^^ { _.toString } 
    def digit: Parser[Int] = """[0-2]{1}""".r ^^ { _.toInt } 

    def expr: Parser[Any] = alpha ~ "." ~ digit ^^ { 
    case al ~ "." ~ di => List(al, di) 
    } 

    def simpleExpression: Parser[Any] = alpha ~ "." ~ rep(alpha ~ ".") ~ digit //^^ { } 
} 

正如你可以看到def expr :Parser[Any]我試圖返回的結果作爲一個列表,因爲在斯卡拉列表是很容易的工作(在我看來)。這是如何將Parser [Any]結果轉換爲List的正確方法?任何人都可以給我任何提示,我可以如何做到這一點def simpleExpression:Parser[Any]

我想使用列表的主要原因是因爲解析和表達後我想能夠使用它。例如,給定表達AB1,如果我給出的「A」,我想消耗的表達用新的表達式結束:B.1(即AB1 - >( a) - > b.1)。這背後的想法是模擬有限狀態自動機。任何提示如何我可以改善我的實施,我們感激。

回答

4

爲了保持事物類型的安全性,我推薦一個解析器,它產生一個字符串列表和一個int列表的元組。也就是說,輸入a.b.a.1將被解析爲(List("a", "b", "a"), 1)。還要注意,alpha的正則表達式被修改爲排除任何不是小寫字母的東西(除t之外)。

class SimpleParser extends RegexParsers { 
    def alpha: Parser[String] = """[a-su-z]{1}""".r ^^ { _.toString } 
    def digit: Parser[Int] = """[0-2]{1}""".r ^^ { _.toInt } 

    def repAlpha: Parser[List[String]] = rep1sep(alpha, ".") 

    def expr: Parser[(List[String], Int)] = repAlpha ~ "." ~ digit ^^ { 
    case alphas ~ _ ~ num => 
     (alphas, num) 
    } 
} 

有了這個SimpleParser的一個實例,這裏是我得到的輸出:

println(parser.parse(parser.expr, "a.b.a.1")) 
// [1.8] parsed: (List(a, b, a),1) 

println(parser.parse(parser.expr, "a.0")) 
// [1.4] parsed: (List(a),0) 
+0

非常感謝你。那麼你將如何去模式匹配元組中的列表呢?它是否像正常模式與列表匹配? – wirdis

+0

我管理。我做的事情如下: def消耗(c:String,t:(List [String],Int)):(列表[String],Int)= {tl_1匹配{case} Nil = >(List(),t._2) case x :: xs => if(x.equalsIgnoreCase(c))(xs,t._2) else(x :: xs,t._2) } } ''' – wirdis

相關問題