Чтобы обойти эту проблему, я создал модуль, который отслеживает последний токен и просматривает список допустимых токенов, чтобы определить, является ли оператор "/" оператором деления или регулярным выражением.
Код ниже:
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 для результата правила. Например:
* +1007 *
setToken устанавливает последний токен и возвращает только что установленный токен, только для того, чтобы он был менее навязчивым к реальному коду лексера.
Фактическое правило для символа "/":
| "/" { setToken (parseDivision lexbuf token regex) }
Также необходимо сбросить токен в EOF, как только анализ будет завершен, или вы можете оказаться в несогласованном состоянии (поскольку последний токен является статической переменной).