0

私は現在、単純な計算の解析に基づいて (F# ツールセットに基づいて) 字句解析と解析について学んでおり、字句解析器が文字列全体を消費するように進んでいないことに行き詰まっています。

let lexeme = LexBuffer<_>.LexemeString
// ...
rule test = parse
  | digit+  { Console.WriteLine("1_" + (lexeme lexbuf)); test lexbuf; }
  | '+'     { Console.WriteLine("2_" + (lexeme lexbuf)); test lexbuf; }
  | '-'     { Console.WriteLine("3_" + (lexeme lexbuf)); test lexbuf; }
  | '*'     { Console.WriteLine("4_" + (lexeme lexbuf)); test lexbuf; }
  | '/'     { Console.WriteLine("5_" + (lexeme lexbuf)); test lexbuf; }
  | '('     { Console.WriteLine("6_" + (lexeme lexbuf)); test lexbuf; }
  | ')'     { Console.WriteLine("7_" + (lexeme lexbuf)); test lexbuf; }
  | eof     { () }

ここで注意してください。たとえば、'test lexbuf'提供する文字列全体が確実に消費されるようにするために、最後に記述する必要があります。

実際の実装ではそれを行わないため、たとえば最初の数字を読み取るだけで、それがすべて取得できます。

rule calculator = parse
  | digit+  { NUMBER (Convert.ToInt32(lexeme lexbuf)) }
  | '+'     { PLUS }
  | '-'     { MINUS }
  | '*'     { TIMES }
  | '/'     { DIV }
  | '('     { LPAREN }
  | ')'     { RPAREN }
  | eof     { EOF }

よく似た構造の例をたくさん見てきました。何が欠けていますか。

4

2 に答える 2

0

テキスト入力に空白や改行が含まれている可能性が高いため、それらを処理するためのルールが必要であると推測しています (つまり、トークンを生成するのではなく、lexbuf を進めてそれらを破棄します)。何かのようなもの:

let whitespace = [' ' '\t' ]
let newline = ('\n' | '\r' '\n')

...

| whitespace { calculator lexbuf }
| newline    { lexbuf.EndPos <- lexbuf.EndPos.NextLine; calculator lexbuf }
于 2014-08-29T14:56:58.873 に答える