Как нестандартный строковый литерал позволяет избежать синтаксической ошибки, генерируемой стандартным строковым литералом? - PullRequest
7 голосов
/ 26 сентября 2019

Исходя из соответствующего раздела документов Julia, я понимаю, что нестандартный строковый литерал, такой как foo"hello, world", эквивалентен явному вызову соответствующего макроса: @foo_str("hello, world").Однако должна быть какая-то дополнительная магия, которую я не понимаю.Рассмотрим формат даты dateformat"\m".Само по себе "\m" выдает синтаксическую ошибку:

julia> "\m"
ERROR: syntax: invalid escape sequence

И такая же синтаксическая ошибка выдается, если я вызываю @dateformat_str("\m"), поскольку строковый литерал "\m", по-видимому, оценивается или перед ним проверяется ошибка.передается макросу:

julia> using Dates

julia> @dateformat_str("\m")
ERROR: syntax: invalid escape sequence

Однако, используя нестандартные строковые литералы:

julia> dateformat"\m"
dateformat"\m"

Это нелогично, потому что я думал, что dateformat"\m" было эквивалентнодо @dateformat_str("\m").Как нестандартный строковый литерал позволяет избежать синтаксической ошибки, генерируемой стандартным строковым литералом?

1 Ответ

7 голосов
/ 26 сентября 2019

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

Для вызовов строковых макросов он делает это .Вызов: parse-raw-literal

Где, как и для обычных строковых литералов , он делает это .С другой стороны, вызов parse-string-literal


@dateformat_str("\m") анализируется как вызов макроса обычного строкового литерала.поэтому он использует более поздние parse-string-literal, что приводит к ошибкам.

Обратите внимание, что те, которые были проанализированы, проанализировали строку в том, что экранируется как "\\m"

julia> dump(:(dateformat"\m"))
Expr
  head: Symbol macrocall
  args: Array{Any}((3,))
    1: Symbol @dateformat_str
    2: LineNumberNode
      line: Int64 1
      file: Symbol REPL[6]
    3: String "\\m

.является макросом необработанной строки, который вообще ничего не делает, но все еще будет анализироваться строкой с использованием parse-raw-literal Он в основном определяется как

macro raw_str(s)
    return s
end
...