この問題を回避するために、最後のトークンを追跡し、有効なトークンのリストを調べて、「/」演算子が除算演算子か正規表現かを確認するモジュールを作成しました。
コードは以下のとおりです。
let mutable lastToken:token = EOF
let setToken token =
lastToken <- token
token
let parseDivision (lexbuf:Lexing.lexbuf) (tokenizer:Lexing.LexBuffer<'a> -> JavascriptParser.token) regexer =
match lastToken.GetType().Name with
| x when invalidRegexPrefix |> List.contains(x) -> DIVIDE
| _ ->
let result = (regexer lexbuf.StartPos "" lexbuf)
REGEX(result)
そしてレクサー内で、ルールの結果に対して setToken を呼び出します。例えば:
| '(' { setToken LPAREN }
setToken は、最後のトークンを設定し、設定されたばかりのトークンを返します。これは、実際のレクサー コードへの影響を少なくするためだけのものです。
「/」文字の実際の規則は次のとおりです。
| "/" { setToken (parseDivision lexbuf token regex) }
また、解析が完了したら、トークンを EOF にリセットする必要があります。そうしないと、一貫性のない状態になる可能性があります (最後のトークンは静的変数であるため)。