Как написать простую грамматику колышка для жидкого языка шаблонов? - PullRequest
2 голосов
/ 12 мая 2019

изменить: вы можете следить за прогрессом здесь: https://github.com/simple-updates/template

Я использую peg.js и пытаюсь написать что-то, что могло бы интерпретировать шаблон как:

hello {{ "world" }}
{% if a %}
  good {{ a }}
{% else %}
  bad
{% endif %}

Я пробовал много вещей, но допустим, это моя отправная точка:

Template
  = ws markup ws

ws = " "*

open_interpolation = "{{"
close_interpolation = "}}"
open_tag = "{%"
close_tag = "%}"

char = . // ?

markup =
  (open_tag tag:char* close_tag)
  { return { 'tag': tag.join('') } } /
  (open_interpolation interpolation:char* close_interpolation)
  { return { 'interpolation': interpolation.join('') } } /
  chars:char*
  { return { 'chars': chars.join('') } }

когда я примеряю строку {{ test }}, например, она будет интерпретировать ее как символы вместо интерполяции.

есть идеи, как мне это сделать?

(очевидно, что было бы сложнее с вложенными "наценками")

Ответы [ 2 ]

1 голос
/ 15 мая 2019

Как примерно так в начале:

Template
 = Atom*

Atom
 = IfTag
 / Interpolation
 / [^{]
 / !"{%" !"{{" "{"

Interpolation
 = "{{" _ Expression _ "}}"

IfTag
 = If Template ( Else Template )? EndIf

If
 = "{%" _ "if" _ Expression _ "%}"

Else
 = "{%" _ "else" _ "%}"

EndIf
 = "{%" _ "endif" _ "%}"

Expression
 = "\"" [^"]* "\""
 / [a-zA-Z]+
 / [0-9]+

_
 = [ \t\n\r]*

Сложная часть здесь - альтернатива !"{%" !"{{" "{" производства Atom, которая гласит:

Если "{%" и "{{" не видно перед текущей позицией, сопоставьте один "{"

0 голосов
/ 12 мая 2019

хорошо, я пока что не во вложенной части чего-либо, но мои теги / интерполяции работают

ключ таков !not_something value

текущая грамматика:

{
    function j(value) {
        return value.join('')
    }
}

Template
  = ws markup:markup ws { return markup }

ws = " "*

open_interpolation = "{{"
close_interpolation = "}}"
open_tag = "{%"
close_tag = "%}"

value = .

not_close_interpolation =
    ws !close_interpolation value:value ws { return value }

not_close_tag =
    ws !close_tag value:value ws { return value }

not_open_tag_or_interpolation =
    !open_interpolation !open_tag value:value { return value }

markup =
    (
      open_interpolation interpolation:not_close_interpolation+ close_interpolation {
          return { 'interpolation': j(interpolation) }
      } /
      open_tag tag:not_close_tag+ close_tag {
          return { 'tag': j(tag) }
      } /
      value:not_open_tag_or_interpolation+ { return j(value) }
    )+
...