3

Scala でパーサーを構築する 2 つのアプローチを見てきました。

1 つ目は、RegexParsers から拡張し、獲得した字句パターンを定義することです。これで私が目にする問題は、キーワードのあいまいさをどのように処理するかをよく理解していないことです. たとえば、キーワードが idents と同じパターンに一致する場合、キーワードは idents として処理されます。

それに対抗するために、StandardTokenParsers を使用してキーワードを指定する方法を示すこのような投稿を見てきました。しかし、正規表現パターンの指定方法がわかりません! はい、StandardTokenParsers には「ident」が付属していますが、必要な他のもの (複雑な浮動小数点数表現、特定の文字列リテラル パターン、エスケープの規則など) は付属していません。

キーワードを指定する機能と、正規表現を使用してトークン パターンを指定する機能の両方を取得するにはどうすればよいでしょうか?

4

2 に答える 2

8

私はRegexParsers- 派生パーサーしか書いていませんが、私がしていることは次のようなものです:

val name: Parser[String] = "[A-Z_a-z][A-Z_a-z0-9]*".r

val kwIf: Parser[String]    = "if\\b".r
val kwFor: Parser[String]   = "for\\b".r
val kwWhile: Parser[String] = "while\\b".r

val reserved: Parser[String] = ( kwIf | kwFor | kwWhile )

val identifier: Parser[String] = not(reserved) ~> name
于 2010-09-22T15:24:00.417 に答える
0

@randall-schulz からの回答に似ていますが、正規表現自体で明示的な否定先読みを使用します。

ここで、emptyはキーワードですがempty?、識別子である必要があります。空の後にnameCharsRE. ヘルパー関数は、そのkwような複数のキーワードに使用されます。

  val nameCharsRE = "[^\\s\",'`()\\[\\]{}|;#]"

  private def kw(kw: String, token: Token) = positioned {
    (s"${kw}(?!${nameCharsRE})").r ^^ { _ => token }
  }
  private def empty        = kw("empty", EMPTY_KW())
  private def and          = kw("and", AND())
  private def or           = kw("or", OR())
于 2021-12-17T13:46:50.530 に答える