PLY с использованием динамических токенов

1

Я пишу программу, которая может анализировать математические статьи, написанные в.tex файлах. Вот что я хочу:

Программа должна обнаруживать начало, конец, разделы, подразделы, подсекции, теоремы, леммы, определения, гипотезы, следствия, предложения, упражнения, обозначения и примеры в математической статье и игнорировать остальную часть содержимого для получения сводки,

Вначале предполагается, что программа сохранит все символы до достижения маркера MT. В этом случае рычаг должен сохранить маркер и введите ig в режим. Затем он должен игнорировать все символы, если он не обнаруживает теорему/лемма/определение / - гипотеза/Следствие/пример/упражнение/обозначение/предложение, в этом случае он временно входит в INITIAL режиме и сохранить его или раздел (подраздел /subsub), в котором случае он должен временно войти в режим sec.

\newtheorem{<name>}{<heading>}[<counter>] и \newtheorem{<name>}[<counter>]{<heading>} определены как TH ptext THCC ptext THC ptext и TH ptext THCS ptext THSC ptext THC соответственно, где ptext представляет собой связку TEXT.

import sys
import logging
from ply.lex import TOKEN

if sys.version_info[0] >= 3:
    raw_input = input

tokens = (
'BT', 'BL', 'BD', 'BCONJ', 'BCOR', 'BE', 'ET', 'EL', 'ED', 'ECONJ', 'ECOR', 'EE', 'SEC', 'SSEC', 'SSSEC', 'ES', 'TEXT','ITEXT','BIBS','MT','BN','EN','BEXE','EEXE','BP','EP','TH','THCS','THSC','THCC','THC',
)

states = (('ig', 'exclusive'), ('sec', 'exclusive'), ('th', 'exclusive'), ('tht','exclusive'),('thc','exclusive'))

logging.basicConfig(
    level = logging.DEBUG,
    filename = "lexlog.txt",
    filemode = "w",
    format = "%(filename)10s:%(lineno)4d:%(message)s"
)
log = logging.getLogger()

th_temp = ''
thn_temp = ''
term_dic = {'Theorem':'','Lemma':'','Corollary':'','Definition':'','Conjecture':'','Example':'','Exercise':'','Notation':'','Proposition':''}
idb_list = ['','','','','','','','','']
ide_list = ['','','','','','','','','']
bb = r'\\begin\{'
eb = r'\\end\{'
ie = r'\}'
def finalize_terms():
    global idb_list
    global ide_list
    if term_dic['Theorem'] != '':
        idb_list[0] = bb + term_dic['Theorem'] + ie
        ide_list[0] = eb + term_dic['Theorem'] + ie
    if term_dic['Lemma'] != '':
        idb_list[1] = bb + term_dic['Lemma'] + ie
        ide_list[1] = eb + term_dic['Lemma'] + ie
    if term_dic['Corollary'] != '':
        idb_list[2] = bb + term_dic['Corollary'] + ie
        ide_list[2] = eb + term_dic['Corollary'] + ie
    if term_dic['Definition'] != '':
        idb_list[3] = bb + term_dic['Definition'] + ie
        ide_list[3] = eb + term_dic['Definition'] + ie
    if term_dic['Conjecture'] != '':
        idb_list[4] = bb + term_dic['Conjecture'] + ie
        ide_list[4] = eb + term_dic['Conjecture'] + ie
    if term_dic['Example'] != '':
        idb_list[5] = bb + term_dic['Example'] + ie
        ide_list[5] = eb + term_dic['Example'] + ie
    if term_dic['Exercise'] != '':
        idb_list[6] = bb + term_dic['Exercise'] + ie
        ide_list[6] = eb + term_dic['Exercise'] + ie
    if term_dic['Notation'] != '':    
        idb_list[7] = bb + term_dic['Notation'] + ie
        ide_list[7] = eb + term_dic['Notation'] + ie
    if term_dic['Proposition'] != '':
        idb_list[8] = bb + term_dic['Proposition'] + ie
        ide_list[8] = eb + term_dic['Proposition'] + ie
    print(idb_list)
    print(ide_list)

Вот некоторые из функций синтаксического анализа:

def t_TH(t):
    r'\\newtheorem\{'
    t.lexer.begin('th')
    return t

def t_th_THCS(t):
    r'\}\['
    t.lexer.begin('thc')
    return t

def t_tht_THC(t):
    r'\}'
    if term_dic.has_key(thn_temp) == False:
        print(f"{thn_temp} is unknown!")
    elif len(th_temp) == 0:
        print(f"No abbreviation for {thn_temp} is found!")
    else:
        term_dic[thn_temp] = th_temp
        print(f"The abbreviation for {thn_temp} is {th_temp}!")
    th_temp = ''
    thn_temp = ''
    t.lexer.begin('INITIAL')
    return t

def t_th_THCC(t):
    r'\}\{'
    t.lexer.begin('tht')
    return t

def t_thc_THSC(t):
    r'\]\{'
    t.lexer.begin('tht')
    return t

@TOKEN(idb_list[0])
def t_ig_BT(t):
    t.lexer.begin('INITIAL')
    return t

@TOKEN(ide_list[0])
def t_ET(t):
    t.lexer.begin('ig')
    return t

def t_INITIAL_sec_thc_TEXT(t):
    r'[\s\S]'
    return t

def t_th_TEXT(t):
    r'[\s\S]'
    th_temp = th_temp + t.value()
    return t

def t_tht_TEXT(t):
    r'[\s\S]'
    thn_temp = thn_temp + t.value()
    return t

def t_ig_ITEXT(t):
    r'[\s\S]'
    pass

import ply.lex as lex
lex.lex(debug=True, debuglog = log)

Вот ошибки: ERROR: /Users/CatLover/Documents/Python_Beta/TexExtractor/texlexparse.py:154: No regular expression defined for rule 't_ET'

Я не знаю, почему регулярное выражение, определенное для 't_ET' и т.д. С помощью @TOKEN, не работает.

  • 2
    Похоже, вы забыли задать вопрос. « Вот то, что я хочу » недостаточно для описания того, с чем вы хотите помочь.
  • 0
    @Johan О, я этого не заметил! Действительно спасибо! По сути, я хотел, чтобы некоторые регулярные выражения зависели от переменных. Это, видимо, не сработало.
Показать ещё 1 комментарий
Теги:
python-3.x
ply

1 ответ

1

Ply - генератор синтаксического анализатора. Он принимает описание парсера/лексера и компилирует из него парсер/лексер. Вы не можете изменить описание языка во время разбора.

В этом конкретном случае вам может быть лучше написать потоковый ("онлайн") сканер. Но если вы хотите использовать Ply, вам будет лучше не пытаться изменить грамматику, чтобы игнорировать части ввода. Просто проанализируйте весь ввод и проигнорируйте те части, которые вам не интересны. Вероятно, вы обнаружите, что код намного проще.

  • 0
    Понимаю. Спасибо! Как мне написать потоковый сканер? Мне не нужно использовать PLY или даже Python. Другие инструменты и языки хороши, пока они работают.
  • 0
    Извините ... но что такое потоковые сканеры?
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню