Как написать парсер с использованием javascript? - PullRequest
0 голосов
/ 10 июля 2020

В нашем продукте мы пытаемся проанализировать следующие различные форматы из заданного фрагмента текста -

  1. ${{node::123456}}
  2. ${{node:123456}}
  3. $fn{{#functionName('abcd',',',' somethingWithASpace')}}
  4. $fn{{#functionName('abcd','#','${{node::123456}}')}}
  5. ${{rmtrqst:someText[]->abcd}}

Пример текста -

  1. Hi, how are you ${{node::123456}}? Your order id is ${{node::636636}}.

или

Your order was placed on $fn{{#dateConverterFunction('abcd','#','${{node::123456}}')}}

Я пробовал использовать Regex /\$((fn)\{{2}(\#|)(\w*)((\(.*\))|([^\$]*))\}{2})/gi - но это мало помогает. Может ли кто-нибудь подсказать мне, как написать для этого парсер?

Грамматика может быть такой -

  1. Каждое выражение начинается с символа $, за которым следует либо fn {{, либо {{
  2. После этого будет строка типа node или #functionName или что-то еще
  3. , за которым может следовать строка, заключенная в круглые скобки (это может содержать все выражение, например $ {{node :: 1234} } внутри - мы должны игнорировать все, что находится внутри скобок
  4. Наконец, он будет закрыт}}

1 Ответ

1 голос
/ 10 июля 2020

Используйте токенизатор и позвольте ему разбить строки до осмысленной структуры.

Библиотека почти. js - популярный выбор для синтаксического анализа нелинейных структур, подобных вашей. Вы можете сохранить свои выражения простыми - или, если выберете иное, библиотека может создать абстрактное синтаксическое дерево для сложного гриммера.

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

Или вы можете напрямую использовать токанизатор, чтобы токанизировать вашу строку.

@{%
const moo = require("moo");

const lexer = moo.compile({
  ws:     /[ \t]+/,
  number: /[0-9]+/,
  word: /[a-z]+/,
  times:  /\*|x/
});
%}

# Pass your lexer object using the @lexer option:
@lexer lexer

# Use %token to match any token of that type instead of "token":
multiplication -> %number %ws %times %ws %number {% ([first, , , , second]) => first * second %}

# Literal strings now match tokens with that text:
trig -> "sin" %number
...