2010-04-30 59 views

回答

6

RegexpParsers允許您使用RE值(通常以"re pattern".r的形式,但同樣也是其他任何Regex實例)。沒有預先定義的詞彙生成(令牌)。

JavaTokenParsers定義爲Java令牌詞法制作:decimalNumberfloatingPointNumberstringLiteralwholeNumberident(標識符)。

StandardTokenParsers定義詞彙產生「...爲一個簡單的類似Scala的語言,它解析關鍵字和標識符,數字文字(整數),字符串和分隔符。其成分實際上在StdLexical中定義。

22

爲了不同的目的,有幾種不同的解析器特徵和基類。

主要特徵是scala.util.parsing.combinator.Parsers。這有大多數主要組合器,如opt,rep,elem,accept等。絕對查看這個文檔,因爲這是你需要知道的大部分內容。實際的Parser類在這裏被定義爲內部類,這也是很重要的。其他重要特徵是scala.util.parsing.combinator.lexical.Scanners。這是解析器的基本特徵,它讀取字符流併產生一個令牌流(也稱爲詞法分析器)。爲了實現這個特性,你需要實現一個whitespace解析器,該解析器讀取空白字符,註釋等。你還需要實現一個token方法,該方法讀取下一個標記。令牌可以是任何你想要的,但它們必須是Scanners.Token的子類。 Lexical延伸ScannersStdLexical延伸Lexical。前者提供了一些有用的基本操作(如digit,letter),而後者實際上定義和解釋了常用的標記(如數字文字,標識符,字符串,保留字)。你只需要定義和reserved,你會得到一些對大多數語言有用的東西。令牌定義在scala.util.parsing.combinator.token.StdTokens

一旦你有了一個詞法分析器,你可以定義一個解析器,它讀取一個標記流(由詞法分析器產生)並生成一個抽象語法樹。分離詞法分析器和分析器是一個好主意,因爲您不需要擔心語法中的空白或註釋或其他複雜因素。如果您使用StdLexical,則可以考慮使用內置解析器的scala.util.parsing.combinator.syntax.StdTokenPasers將令牌轉換爲值(例如,StringLit轉換爲String)。我不確定與StandardTokenParsers有什麼不同。如果您定義自己的令牌類,則應簡單使用Parsers

您特別詢問了有關RegexParsersJavaTokenParsersRegexParsers是一個擴展Parsers與一個額外的組合:regex,這完全符合你的期望。如果您想使用正則表達式來匹配令牌,請將RegexParsers混合到您的詞法分析器中。JavaTokenParsers提供了一些解析器,它們從Java語法(如標識符,整數)中抽出令牌,但沒有LexicalStdLexical的令牌行李。總之,您可能需要兩個解析器:一個讀取字符並生成標記,另一個讀取標記並生成AST。首先使用基於LexicalStdLexical的東西。取決於您是否使用StdLexical,根據ParsersStdTokenParsers第二次使用。