PLY с использованием динамических токенов - PullRequest
0 голосов
/ 14 октября 2018

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

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

В начале программа должна сохранять все символы до достижения токена MT.В этом случае рычаг должен сохранить токен и войти в режим ig.Затем он должен игнорировать все символы, если он не обнаружит теорему / лемму / определение / гипотезу / следствие / пример / упражнение / нотацию / предложение, в этом случае он временно входит в режим INITIAL и сохраняет его или раздел (sub / 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, не работают.

1 Ответ

0 голосов
/ 16 октября 2018

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

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

...