Читать буквально из метамодели

Я хочу спросить, возможно ли прочитать - из моего кода Python - литерал, который я определил в метамодели. Это может быть лучше всего объяснено на примере. Допустим, это моя метамодель (вдохновленная примером Entitiy):

EntityModel:
  entities+=Entity
;

Entity:
  EntityKeyword name=ID '{'
    attributes+=Attribute
  '}'
;

EntityKeyword:
  'entity'
;

Теперь, если я проанализирую это, у меня будет доступ к любым объектам, которые были определены во входном файле. Но я также хочу иметь возможность читать литерал "entity", который определен в правиле EntityKeyword. Я пытаюсь сделать это, чтобы избежать жесткого кодирования значения ("сущности") в моем собственном коде.

Я не смог найти способ сделать это. Является ли это возможным?

Я прочитал документацию, а также попробовал встроенные объекты. Мне не повезло.

Надеюсь, у меня есть смысл.

Благодарю.

ОБНОВИТЬ:

Спасибо за ответы - и извините за мой поздний ответ.

Теперь я вижу, что мой пример был плохим. Я прошу прощения за это.

Я поиграл с textX, прочитал еще немного документации и наткнулся на этот раздел:

"textX интегрируется с системой типизации Python. В textX нет возвращаемых ключевых слов. Класс, используемый для правила, будет динамически создаваемым классом Python для всех несоответствующих правил. Разработчик языка может предоставить класс, используя регистрацию пользовательских классов в метамодели. правило имеет [тип соответствия], поэтому всегда возвращает строку Python или некоторые базовые типы Python для унаследованных правил BASETYPES." Типы, используемые для правил

Выделенная часть звучит очень похоже на то, чего я пытаюсь достичь. Я постараюсь сделать это, но в противном случае очень ценю пример этого - если у вас есть время для этого.

С уважением DonHaugaard

1 ответ

Решение

Итак, я нашел решение своей проблемы.

В чем была моя проблема? Я хотел избежать жесткого кодирования любого литерала в моей метамодели. Например

EntityKeyword:
  'entity'
;

является простым классом типа соответствия, который пытается соответствовать литералу 'entity'. Если это ключевое слово является именем необязательного параметра для объекта, то при выполнении поиска "hasattr(obj, 'entity')" мне пришлось бы жестко закодировать это ключевое слово в моем исходном коде Python. Это означает, что у меня есть значение ключевого слова для поддержки в 2 местах - в моей метамодели и в моем исходном коде.

Решение, которое я нашел, очень просто. Я просто загружаю метамодель из строки, используя "metamodel_from_str()". Как бы это выглядело?

from string import Template
from textx.metamodel import metamodel_from_str

EXTEND_KEYWORD = 'entity'  
GRAMMAR=Template("""
EntityKeyword:
    '$ext_keyword'
;
""").substitute(ext_keyword=EXTEND_KEYWORD)

stackru_mm = metamodel_from_str(GRAMMAR)

Здесь я определяю свою метамодель как строку и использую string.Template ( https://docs.python.org/3/library/string.html) для замены любых ключевых слов. После этого я могу загрузить метамодель в виде строки. Теперь мне нужно поддерживать только один литерал (атрибут "EXTEND_KEYWORD"), и я могу свободно делать "hasattr(obj, EXTEND_KEYWORD)".

Недостатком этого подхода, конечно, является то, что метаязык может быть загрязнен различными символами ($$), поскольку я использую string.Template для замены любых ключевых слов.

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

Другие вопросы по тегам