2010-01-13 2 views
2

Я пытаюсь использовать литералы регулярного выражения lex javascript. Они начинаются с «/» и заканчиваются «/» (а иногда и некоторыми другими модификаторами). Проблема в том, что единственный способ определить, является ли это регулярным выражением, а не оператором деления, - это прочитать токены, предшествующие символу «/».fslex lexing регулярные выражения javascript

Здесь можно прочитать немного больше об этом here.

Как бы то ни было, я не могу найти документацию о том, как получить предыдущий токен. Надеюсь, это возможно, и кто-то может сказать мне, как это сделать.

Спасибо.

ответ

1

Чтобы обойти эту проблему, я создал модуль, который отслеживает последний токен и просматривает список действительных токенов, чтобы определить, является ли оператор «/» оператором деления или регулярным выражением.

код ниже:

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 после того, как синтаксический анализ завершается или может находиться в неустойчивом состоянии (так как последний маркер статическая переменная).

1

Насколько я знаю, нет способа получить предыдущий токен (но я не пробовал это, и я использовал FSLex совсем некоторое время назад). Я думаю, вы могли бы сохранить параметр, определяющий последний обработанный токен, а затем использовать его, чтобы решить, что делать, когда вы находите символ «/».

В любом случае, не могли бы вы опубликовать некоторый пример кода, который у вас есть (например, только часть, которая касается этой проблемы)? Было бы намного проще, чтобы ответить на ваш вопрос, если мы будем видеть некоторые примеры кода (и если я мог бы попытаться вставить его в моей Visual Studio и посмотреть, смогу ли я что-нибудь придумаю!)

T.