Upgrade to Pro — share decks privately, control downloads, hide ads and more …

SimplePEG и Tchaikovsky - универсальная валидация

SimplePEG и Tchaikovsky - универсальная валидация

Алексей Охрименко (Senior JavaScript Developer at IPONWEB) @ Moscow Python Meetup 55

"Как создать универсальную валидацию для Backend и Frontend и как валидировать сложные текстовые поля".

Видео: http://www.moscowpython.ru/meetup/55/simplepeg-tchaikovsky/

Moscow Python Meetup

April 24, 2018
Tweet

More Decks by Moscow Python Meetup

Other Decks in Programming

Transcript

  1. 4

  2. 27

  3. RFC 822, 2822, 5322 • https://tools.ietf.org/html/rfc822 ( 1982 год )

    • https://tools.ietf.org/html/rfc2822 ( 2001 год ) • https://tools.ietf.org/html/rfc5322 ( 2008 год )
  4. class State(object): text = "" position = 0 class Node(object):

    match = "" children = None start_position = None end_position = None
  5. def string(rule, state): if state.text[state.position:state.position+len(rule)] == rule: start_position = state.position

    state.position += len(rule) return Node( type='string', match=rule, start_position=start_position, end_position=state.position ) else: return False
  6. def string(rule, state): if state.text[state.position:state.position+len(rule)] == rule: start_position = state.position

    state.position += len(rule) return Node( type='string', match=rule, start_position=start_position, end_position=state.position ) else: return False
  7. def string(rule, state): if state.text[state.position:state.position+len(rule)] == rule: start_position = state.position

    state.position += len(rule) return Node( type='string', match=rule, start_position=start_position, end_position=state.position ) else: return False
  8. def string(rule, state): if state.text[state.position:state.position+len(rule)] == rule: start_position = state.position

    state.position += len(rule) return Node( type='string', match=rule, start_position=start_position, end_position=state.position ) else: return False
  9. def string(rule, state): if state.text[state.position:state.position+len(rule)] == rule: start_position = state.position

    state.position += len(rule) return Node( type='string', match=rule, start_position=start_position, end_position=state.position ) else: return False
  10. def string(rule): def _(state): if state.text[state.position:state.position+len(rule)] == rule: start_position =

    state.position state.position += len(rule) return Node( type='string', match=rule ) else: return False return _
  11. def string(rule): def _(state): if state.text[state.position:state.position+len(rule)] == rule: start_position =

    state.position state.position += len(rule) return Node( type='string', match=rule ) else: return False return _
  12. def string(rule): def _(state): if state.text[state.position:state.position+len(rule)] == rule: start_position =

    state.position state.position += len(rule) return Node( type='string', match=rule ) else: return False return _
  13. def sequence(parsers): def _(state): asts = [] start_position = state.position

    for parser in parsers: ast = parser(state) if ast: asts.append(ast) else: return False return Node( type='sequence', children=asts ) return _
  14. def sequence(parsers): def _(state): asts = [] start_position = state.position

    for parser in parsers: ast = parser(state) if ast: asts.append(ast) else: return False return Node( type='sequence', children=asts ) return _
  15. def sequence(parsers): def _(state): asts = [] start_position = state.position

    for parser in parsers: ast = parser(state) if ast: asts.append(ast) else: return False return Node( type='sequence', children=asts ) return _
  16. def sequence(parsers): def _(state): asts = [] start_position = state.position

    for parser in parsers: ast = parser(state) if ast: asts.append(ast) else: return False return Node( type='sequence', children=asts ) return _
  17. def sequence(parsers): def _(state): asts = [] start_position = state.position

    for parser in parsers: ast = parser(state) if ast: asts.append(ast) else: return False return Node( type='sequence', children=asts ) return _
  18. def sequence(parsers): def _(state): asts = [] start_position = state.position

    for parser in parsers: ast = parser(state) if ast: asts.append(ast) else: return False return Node( type='sequence', children=asts ) return _
  19. def sequence(parsers): def _(state): asts = [] start_position = state.position

    for parser in parsers: ast = parser(state) if ast: asts.append(ast) else: return False return Node( type='sequence', children=asts ) return _
  20. parser = sequence([ string('a'), sequence([ string('b') string('c') ]) ]) parser({})

    { type: 'sequence', children: [ { type: 'string', match: 'a' }, { type: 'sequence', children: [ { type: 'string', match: 'b' }, { type: 'string', match: 'c' }, ] } ] }
  21. // Rule // Parsing Expression // Parsing Expression // Sequence:

    e1 e2 e3 // Ordered choice: e1 / e2 // Zero-or-more: e* // One-or-more: e+ // Optional: e? // And-predicate: &e // Not-predicate: !e // Atomic Parsing Expression: // String // RegExp // EOF PEG (7 / 3)
  22. // Rule // Parsing Expression // Parsing Expression // Sequence:

    e1 e2 e3 // Ordered choice: e1 / e2 // Zero-or-more: e* // One-or-more: e+ // Optional: e? // And-predicate: &e // Not-predicate: !e // Atomic Parsing Expression: // String // RegExp // EOF Rule e -> e
  23. // Rule // Parsing Expression // Parsing Expression // Sequence:

    e1 e2 e3 // Ordered choice: e1 / e2 // Zero-or-more: e* // One-or-more: e+ // Optional: e? // And-predicate: &e // Not-predicate: !e // Atomic Parsing Expression: // String // RegExp // EOF Sequence e1 e2 e3
  24. // Rule // Parsing Expression // Parsing Expression // Sequence:

    e1 e2 e3 // Ordered choice: e1 / e2 // Zero-or-more: e* // One-or-more: e+ // Optional: e? // And-predicate: &e // Not-predicate: !e // Atomic Parsing Expression: // String // RegExp // EOF Ordered choice e1 / e2
  25. // Rule // Parsing Expression // Parsing Expression // Sequence:

    e1 e2 e3 // Ordered choice: e1 / e2 // Zero-or-more: e* // One-or-more: e+ // Optional: e? // And-predicate: &e // Not-predicate: !e // Atomic Parsing Expression: // String // RegExp // EOF Zero-or-more e*
  26. // Rule // Parsing Expression // Parsing Expression // Sequence:

    e1 e2 e3 // Ordered choice: e1 / e2 // Zero-or-more: e* // One-or-more: e+ // Optional: e? // And-predicate: &e // Not-predicate: !e // Atomic Parsing Expression: // String // RegExp // EOF One-or-more e+
  27. // Rule // Parsing Expression // Parsing Expression // Sequence:

    e1 e2 e3 // Ordered choice: e1 / e2 // Zero-or-more: e* // One-or-more: e+ // Optional: e? // And-predicate: &e // Not-predicate: !e // Atomic Parsing Expression: // String // RegExp // EOF Optional e?
  28. // Rule // Parsing Expression // Parsing Expression // Sequence:

    e1 e2 e3 // Ordered choice: e1 / e2 // Zero-or-more: e* // One-or-more: e+ // Optional: e? // And-predicate: &e // Not-predicate: !e // Atomic Parsing Expression: // String // RegExp // EOF And-predicate &e
  29. // Rule // Parsing Expression // Parsing Expression // Sequence:

    e1 e2 e3 // Ordered choice: e1 / e2 // Zero-or-more: e* // One-or-more: e+ // Optional: e? // And-predicate: &e // Not-predicate: !e // Atomic Parsing Expression: // String // RegExp // EOF Not-predicate !e
  30. // Rule // Parsing Expression // Parsing Expression // Sequence:

    e1 e2 e3 // Ordered choice: e1 / e2 // Zero-or-more: e* // One-or-more: e+ // Optional: e? // And-predicate: &e // Not-predicate: !e // Atomic Parsing Expression: // String // RegExp // EOF String «something»
  31. // Rule // Parsing Expression // Parsing Expression // Sequence:

    e1 e2 e3 // Ordered choice: e1 / e2 // Zero-or-more: e* // One-or-more: e+ // Optional: e? // And-predicate: &e // Not-predicate: !e // Atomic Parsing Expression: // String // RegExp // EOF RegExp [a-zA-Z0-9]
  32. // Rule // Parsing Expression // Parsing Expression // Sequence:

    e1 e2 e3 // Ordered choice: e1 / e2 // Zero-or-more: e* // One-or-more: e+ // Optional: e? // And-predicate: &e // Not-predicate: !e // Atomic Parsing Expression: // String // RegExp // EOF EOF end of file
  33. def visit(self, node): if node.children: children = [self.visit(child) for child

    in node.children] node.children = children return getattr(self, node.action)(node)
  34. def visit(self, node): if node.children: children = [self.visit(child) for child

    in node.children] node.children = children return getattr(self, node.action)(node)
  35. def visit(self, node): if node.children: children = [self.visit(child) for child

    in node.children] node.children = children return getattr(self, node.action)(node)