Регулярные выражения JavaScript
Я пытаюсь lex JavaScript регулярных выражений литералов. Они начинаются с "/" и заканчиваются "/" (а иногда и некоторыми другими модификаторами). Проблема в том, что единственный способ определить, является ли оно регулярным выражением, а не оператором деления, - это прочитать токены, предшествующие символу "/".
Подробнее об этом можно прочитать здесь.
На самом деле, я не могу найти документацию о том, как получить предыдущий токен. Надеюсь, это возможно, и кто-то может сказать мне, как.
Благодарю.
2 ответа
Чтобы обойти эту проблему, я создал модуль, который отслеживает последний токен и просматривает список допустимых токенов, чтобы определить, является ли оператор "/" оператором деления или регулярным выражением.
Код ниже:
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, как только анализ будет завершен, или вы можете оказаться в несогласованном состоянии (поскольку последний токен является статической переменной).
Насколько я знаю, нет никакого способа получить предыдущий токен (но я не пробовал это, и я использовал FSLex довольно давно). Я думаю, вы могли бы сохранить параметр, указывающий последний обработанный токен, а затем использовать его, чтобы решить, что делать, когда вы найдете символ "/".
В любом случае, не могли бы вы опубликовать пример кода, который у вас есть (например, просто часть, которая занимается этой проблемой)? Было бы намного проще ответить на ваш вопрос, если бы мы увидели некоторый пример кода (и если бы я мог попытаться вставить его в свою Visual Studio и посмотреть, смогу ли я что-нибудь выяснить!)
Т.