Python - Жаворонок - Грамматика - Строка - PullRequest
0 голосов
/ 04 мая 2020

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

Мне удалось заставить его работать с регулярным выражением и токенизатором методы, но в будущем строк будет больше, и я не хочу передавать все через регулярное выражение или добавлять больше кода в токенизатор, вместо этого я использую lark. Я начинаю жаворонок, поэтому было сложно разобрать следующую строку.

'filter:property-insensitive:name:%Name'
'filter:property-insensitive:gender:M:F:U'
'filter:age:on:${today}:Equal:26:years'
'filter:date:Equal:${today}'
'filter:property:Type:regular:temp'
'filter:property:Status:active:unknown'
from lark import Lark

parser = Lark(r"""
        start: greet greet greet
        greet: "filter"
            | ":" -> seperator
            | "property-insensitive" -> key_case
            | ":" -> seperator
    """, parser="lalr")


sample_conf = """filter:property-insensitive:Surname:%Name"""

print(parser.parse(sample_conf).pretty())

Попробуйте 2:

import lark
grammar = r'''start: instruction

?instruction: filters_function

FUNCNAME: (LETTER+) (LETTER+|DIGIT+|"_")* // no parentheses allowed in the func name
PROPERTY: (LETTER+) (LETTER+|DIGIT+|"-")*
FIELD: (LETTER+) (LETTER+|DIGIT+|"-"|"_")*
VALUE: (LETTER+) (LETTER+|DIGIT+|"-"|"%")*
ARGSEP: ":" // argument separator
WORDSEP: ":" // word separator
CONDSEP: ":" // condition separator
STAR: "*"
filters_function: FUNCNAME PROPERTY FIELD  VALUE*

%import common.LETTER
%import common.WORD
%import common.DIGIT
%ignore ARGSEP
%ignore WORDSEP
'''

parser = lark.Lark(grammar, parser='earley') # lalr
print(parser.parse("filter:property-insensitive:Surname_name:Name"))

Попробуйте 3:

import lark
grammar = r'''start: instruction

?instruction: filters_function
property:"property-insensitive"         -> property_insensitive
        | "property"                    -> property
        | "age"                         -> age_filter
        | "date"                        -> date_filter

FUNCNAME: (LETTER+) (LETTER+|DIGIT+|"_")* // no parentheses allowed in the func name

FIELD: (LETTER+) (LETTER+|DIGIT+|"-"|"_")*
VALUE: (LETTER+) (LETTER+|DIGIT+|"-")*
ARGSEP: ":" // argument separator
WORDSEP: ":" // word separator
CONDSEP: ":" // condition separator
STAR: "*"
filters_function: FUNCNAME property FIELD  VALUE *

%import common.LETTER
%import common.WORD
%import common.DIGIT
%ignore ARGSEP
%ignore WORDSEP
%ignore " "
%ignore "$"
%ignore "{"
%ignore "}"
%ignore "}"
%ignore "0".."9"
'''

parser = lark.Lark(grammar, parser='earley') # lalr
print(parser.parse("filter:property-insensitive:Surname:Name"))
print(parser.parse("filter:property-insensitive:Sex:M:F:U"))
print(parser.parse("filter:age:on:${today}:Equal:26:years"))
print(parser.parse("filter:date:Equal:${today}"))
print(parser.parse("filter:property:Registration_Type:regular:temp"))

Попробуйте 3 - Проблемы:

  • Я не могу выполнить ИЛИ для поля и значений, если свойство == age | date считать остальные значения как VALUE

  • Если мы найдем свойство, которое я хочу, чтобы строка была в выводе дерева, в настоящее время это [] Tree(start, [Tree(filters_function, [Token(FUNCNAME, 'filter'), Tree(property_insensitive, []), Token(FIELD, 'Surname'), Token(VALUE, 'Name')])])

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

Попробуйте 4:

import lark
grammar = r'''start: instruction

?instruction: filters_function

property: "property-insensitive"        -> property_insensitive
        | "property"                    -> property
property_date: "age"                    -> age_filter
             | "date"                   -> date_filter



// To run over special characters
TEXT: (LETTER+) (LETTER+|DIGIT+|"-"|"_")*
FILTER: TEXT
SPECIAL_VALUE: "${" (LETTER+) (LETTER+|DIGIT+|"-"|"_") "}" *
WILD_CARD: "%" TEXT | TEXT | NUMBER
VALUE: WILD_CARD|SPECIAL_VALUE

ARGSEP: ":" // argument separator

STAR: "*"
filters_function: FILTER (property | property_date) VALUE *

// find the whitespace so we can ignore
WHITESPACE: (" " | "\n")+

%ignore WHITESPACE
%import common.LETTER
%import common.WORD
%import common.DIGIT
%import common.INT -> NUMBER
%ignore ARGSEP
%ignore " "
'''

parser = lark.Lark(grammar, parser='earley') # lalr
print(parser.parse("filter:property-insensitive:Surname:%Name"))
print(parser.parse("filter:property-insensitive:Sex:M:F:U"))
print(parser.parse("filter:age:on:${today}:Equal:26:years"))
print(parser.parse("filter:date:Equal:${today}"))
print(parser.parse("filter:property:Registration_Type:regular:temp"))

Вывод:

Tree(start, [Tree(filters_function, [Token(FILTER, 'filter'), Tree(property_insensitive, []), Token(VALUE, 'Surname'), Token(VALUE, '%Name')])])
Tree(start, [Tree(filters_function, [Token(FILTER, 'filter'), Tree(property_insensitive, []), Token(VALUE, 'Sex'), Token(VALUE, 'M'), Token(VALUE, 'F'), Token(VALUE, 'U')])])
Tree(start, [Tree(filters_function, [Token(FILTER, 'filter'), Tree(age_filter, []), Token(VALUE, 'on'), Token(VALUE, '${today}'), Token(VALUE, 'Equal'), Token(VALUE, '26'), Token(VALUE, 'years')])])
Tree(start, [Tree(filters_function, [Token(FILTER, 'filter'), Tree(date_filter, []), Token(VALUE, 'Equal'), Token(VALUE, '${today}')])])
Tree(start, [Tree(filters_function, [Token(FILTER, 'filter'), Tree(property, []), Token(VALUE, 'Registration_Type'), Token(VALUE, 'regular'), Token(VALUE, 'temp')])])

Проблема:

  • Мне не удалось найти способ вернуть значение для дерево Tree(date_filter, [])

Было бы неплохо, если бы мне указали на хороший учебник для начинающих в жаворонке.

...