Лексирование строк в ocamllex

У меня были некоторые проблемы с попыткой найти хороший пример для обработки строк в ocamllex. Я нашел пример настольного калькулятора несколько полезным, но на самом деле не нашел способа реализовать его аналогичным образом, в котором он также использует строки, вот пример, на который я ссылаюсь:

        {
        open Parser        (* The type token is defined in parser.mli *)
        exception Eof
        }
        rule token = parse
            [' ' '\t']     { token lexbuf }     (* skip blanks *)
          | ['\n' ]        { EOL }
          | ['0'-'9']+ as lxm { INT(int_of_string lxm) }
          | '+'            { PLUS }
          | '-'            { MINUS }
          | '*'            { TIMES }
          | '/'            { DIV }
          | '('            { LPAREN }
          | ')'            { RPAREN }
          | eof            { raise Eof }

Любая помощь будет принята с благодарностью.


person C H    schedule 21.02.2021    source источник
comment
Вы видели главу о парсинге JSON в Real World OCaml? раздел гибкости подробно описывает обработку строк dev.realworldocaml.org/parsing -with-ocamllex-and-menhir.html   -  person zehnpaard    schedule 22.02.2021
comment
*лексический раздел   -  person zehnpaard    schedule 22.02.2021


Ответы (1)


Я предполагаю, что вы говорите о строках в двойных кавычках, как в OCaml. Сложность с лексированием строк заключается в том, что они требуют некоторого механизма экранирования, позволяющего представлять кавычки (и, как правило, самого механизма экранирования).

Вот упрощенная версия кода для строк из самого лексера OCaml:

let string_buff = Buffer.create 256

let char_for_backslash = function
  | 'n' -> '\010'
  | 'r' -> '\013'
  | 'b' -> '\008'
  | 't' -> '\009'
  | c   -> c

. . .

let backslash_escapes =
    ['\\' '\'' '"' 'n' 't' 'b' 'r' ' ']

. . .

rule main = parse
. . .
| '"'
    { Buffer.clear string_buff;
      string lexbuf;
      STRING (Buffer.contents string_buff) }
. . .

and string = parse
| '"'
    { () }
| '\\' (backslash_escapes as c)
    { Buffer.add_char string_buff (char_for_backslash c);
      string lexbuf }
| _ as c
    { Buffer.add_char string_buff c;
      string lexbuf }

Изменить. Ключевой особенностью этого кода является то, что он использует второй сканер (с именем string) для выполнения лексического анализа в строке, заключенной в кавычки. Обычно это делает вещи чище, чем попытки написать один сканер для всех токенов — некоторые токены довольно сложны. Подобный прием часто используется для сканирования комментариев.

person Jeffrey Scofield    schedule 22.02.2021