Как токенизировать текст, используя грамматики textmate в python? - PullRequest
0 голосов
/ 27 февраля 2019

Я хотел бы узнать, как использовать грамматики textmate для идентификации / извлечения / выбора областей из заданного текста.

Я не нашел ни одной библиотеки Python, готовой к использованию после многих часов поиска в Google ... вместо этого я только нашел несколько решений, написанных на других языках, таких как:

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

Есть 2 метода, которые я хотел бы узнать, как реализовать самостоятельно (взято из SublimeText API , которые я не могу использовать напрямую, так как код не представлен в виде библиотеки):

  • extract_scope(point): Возвращает экстент имени области синтаксиса, назначенного символу в данной точке.
  • scope_name(point): Возвращает имя области синтаксиса, назначенное персонажу в данной точке.

В данный момент у меня есть этот скелет (не реализован, потому что я не знаюкак):

ini.json

{
    "fileTypes": [
        "ini",
        "INI",
        "inf",
        "INF",
        "reg",
        "REG",
        "lng",
        "cfg",
        "CFG",
        "url",
        "URL",
        ".editorconfig"
    ],
    "name": "INI",
    "patterns": [
        {
            "captures": {
                "1": {
                    "name": "punctuation.definition.comment.ini"
                }
            },
            "match": "^\\s*(;|#).*$\\n?",
            "name": "comment.line.semicolon.ini"
        },
        {
            "captures": {
                "1": {
                    "name": "punctuation.definition.section.ini"
                },
                "2": {
                    "name": "entity.section.ini"
                },
                "3": {
                    "name": "punctuation.definition.section.ini"
                }
            },
            "match": "^\\s*(\\[)(.*?)(\\])",
            "name": "meta.tag.section.ini"
        },
        {
            "captures": {
                "1": {
                    "name": "meta.property.ini"
                },
                "10": {
                    "name": "comment.declarationline.semicolon.ini"
                },
                "2": {
                    "name": "punctuation.definition.quote.ini"
                },
                "3": {
                    "name": "keyword.name.ini"
                },
                "4": {
                    "name": "punctuation.definition.quote.ini"
                },
                "5": {
                    "name": "punctuation.definition.equals.ini"
                },
                "6": {
                    "name": "meta.value.ini"
                },
                "7": {
                    "name": "punctuation.definition.quote.ini"
                },
                "8": {
                    "name": "string.name.value.ini"
                },
                "9": {
                    "name": "punctuation.definition.quote.ini"
                }
            },
            "match": "^(\\s*([\"']?)(.+?)(\\2)\\s*(=))?\\s*(([\"']?)(.*?)(\\7))\\s*(;.*)?$\\n?",
            "name": "meta.declaration.ini"
        }
    ],
    "scopeName": "source.ini",
    "uuid": "957acd74-6d7c-4732-a25b-5f66a1e637cd"
}

mcve.py

import json
import textwrap
from oniguruma import onigmo
from pathlib import Path


TMLANGUAGE = json.loads(Path("ini.json").read_text())

SAMPLE = textwrap.dedent("""\
    [title1]

    #=

    a=bcd

    #=

    e=11


    [title2]

    #=e=11
""")


def scope_name(text, pt):
    raise NotImplementedError


def extract_scope(text, pt):
    raise NotImplementedError


if __name__ == '__main__':
    for i, c in enumerate(SAMPLE):
        try:
            print("{:<20}{:<80}{}".format(
                repr(c),
                repr(extract_scope(SAMPLE, i))),
                scope_name(SAMPLE, i)
            )
        except NotImplementedError as e:
            print("{:<20}{:<80}{}".format(repr(c), "UNIMPLEMENTED", "UNIMPLEMENTED"))

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

Для того, чтобы полностью понять, что я пытаюсьДостигните здесь, позвольте мне опубликовать то, что вы должны выводить как для функций extract_scope, так и scope_name для предоставленного образца SAMPLE (когда они будут реализованы):

'['                 '[title1'                                                                       source.ini meta.tag.section.ini punctuation.definition.section.ini 
't'                 'title1'                                                                        source.ini meta.tag.section.ini entity.section.ini 
'i'                 'title1'                                                                        source.ini meta.tag.section.ini entity.section.ini 
't'                 'title1'                                                                        source.ini meta.tag.section.ini entity.section.ini 
'l'                 'title1'                                                                        source.ini meta.tag.section.ini entity.section.ini 
'e'                 'title1'                                                                        source.ini meta.tag.section.ini entity.section.ini 
'1'                 'title1'                                                                        source.ini meta.tag.section.ini entity.section.ini 
']'                 'title1]'                                                                       source.ini meta.tag.section.ini punctuation.definition.section.ini 
'\n'                '[title1]\n\n#=\n\na=bcd\n\n#=\n\ne=11\n\n\n[title2]\n\n#=e=11'                 source.ini 
'\n'                '\n'                                                                            source.ini meta.declaration.ini 
'#'                 '#=\n'                                                                          source.ini comment.line.semicolon.ini punctuation.definition.comment.ini 
'='                 '#=\n'                                                                          source.ini comment.line.semicolon.ini 
'\n'                '#=\n'                                                                          source.ini comment.line.semicolon.ini 
'\n'                '\na=bcd\n\n'                                                                   source.ini meta.declaration.ini 
'a'                 'a='                                                                            source.ini meta.declaration.ini meta.property.ini keyword.name.ini 
'='                 'a='                                                                            source.ini meta.declaration.ini meta.property.ini punctuation.definition.equals.ini 
'b'                 '=bcd'                                                                          source.ini meta.declaration.ini meta.value.ini string.name.value.ini 
'c'                 '=bcd'                                                                          source.ini meta.declaration.ini meta.value.ini string.name.value.ini 
'd'                 '=bcd'                                                                          source.ini meta.declaration.ini meta.value.ini string.name.value.ini 
'\n'                '\na=bcd\n\n'                                                                   source.ini meta.declaration.ini 
'\n'                '\na=bcd\n\n'                                                                   source.ini meta.declaration.ini 
'#'                 '#=\n'                                                                          source.ini comment.line.semicolon.ini punctuation.definition.comment.ini 
'='                 '#=\n'                                                                          source.ini comment.line.semicolon.ini 
'\n'                '#=\n'                                                                          source.ini comment.line.semicolon.ini 
'\n'                '\ne=11\n\n\n'                                                                  source.ini meta.declaration.ini 
'e'                 'e='                                                                            source.ini meta.declaration.ini meta.property.ini keyword.name.ini 
'='                 'e='                                                                            source.ini meta.declaration.ini meta.property.ini punctuation.definition.equals.ini 
'1'                 '=11'                                                                           source.ini meta.declaration.ini meta.value.ini string.name.value.ini 
'1'                 '=11'                                                                           source.ini meta.declaration.ini meta.value.ini string.name.value.ini 
'\n'                '\ne=11\n\n\n'                                                                  source.ini meta.declaration.ini 
'\n'                '\ne=11\n\n\n'                                                                  source.ini meta.declaration.ini 
'\n'                '\ne=11\n\n\n'                                                                  source.ini meta.declaration.ini 
'['                 '[title2'                                                                       source.ini meta.tag.section.ini punctuation.definition.section.ini 
't'                 'title2'                                                                        source.ini meta.tag.section.ini entity.section.ini 
'i'                 'title2'                                                                        source.ini meta.tag.section.ini entity.section.ini 
't'                 'title2'                                                                        source.ini meta.tag.section.ini entity.section.ini 
'l'                 'title2'                                                                        source.ini meta.tag.section.ini entity.section.ini 
'e'                 'title2'                                                                        source.ini meta.tag.section.ini entity.section.ini 
'2'                 'title2'                                                                        source.ini meta.tag.section.ini entity.section.ini 
']'                 'title2]'                                                                       source.ini meta.tag.section.ini punctuation.definition.section.ini 
'\n'                '[title1]\n\n#=\n\na=bcd\n\n#=\n\ne=11\n\n\n[title2]\n\n#=e=11'                 source.ini 
'\n'                '\n'                                                                            source.ini meta.declaration.ini 
'#'                 '#=e=11'                                                                        source.ini comment.line.semicolon.ini punctuation.definition.comment.ini 
'='                 '#=e=11'                                                                        source.ini comment.line.semicolon.ini 
'e'                 '#=e=11'                                                                        source.ini comment.line.semicolon.ini 
'='                 '#=e=11'                                                                        source.ini comment.line.semicolon.ini 
'1'                 '#=e=11'                                                                        source.ini comment.line.semicolon.ini 
'1'                 '#=e=11'                                                                        source.ini comment.line.semicolon.ini 

Я поднял.ini tmLanguage, поскольку он кажется одним из самых простых в мире, но в идеале я хотел бы иметь возможность загружать и использовать любой тип tmLanguage.

ВОПРОС: Не могли бы выпредоставить реализацию (или точное правильное объяснение, которое я смог реализовать самостоятельно) как scope_name, так и extract_scope функции?Реализации должны давать разумный вывод, аналогичный приведенному выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...