Shiyan12

syntagrus.py

Dec 19th, 2019
218
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.86 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. '''
  4. Created on Nov 21, 2011
  5. @author: alexpak
  6. '''
  7. import os
  8. import sqlite3
  9. import xml.parsers.expat
  10. import glob
  11. from optparse import OptionParser
  12. from collections import namedtuple
  13.  
  14. word_t = namedtuple('word_t', ['lemma', 'pos', 'feat', 'id', 'dom', 'link'])
  15. feat_ru_en = {
  16.     'ЕД': 'sg',
  17.     'МН': 'pl',
  18.     'ЖЕН': 'f',
  19.     'МУЖ': 'm',
  20.     'СРЕД': 'n',
  21.     'ИМ': 'nom',
  22.     'РОД': 'gen',
  23.     'ДАТ': 'dat',
  24.     'ВИН': 'acc',
  25.     'ТВОР': 'ins',
  26.     'ПР': 'prep',
  27.     'ПАРТ': 'gen2',
  28.     'МЕСТН': 'loc',
  29.     'ОД': 'anim',
  30.     'НЕОД': 'inan',
  31.     'ИНФ': 'inf',
  32.     'ПРИЧ': 'adjp',
  33.     'ДЕЕПР': 'advp',
  34.     'ПРОШ': 'pst',
  35.     'НЕПРОШ': 'npst',
  36.     'НАСТ': 'prs',
  37.     '1-Л': '1p',
  38.     '2-Л': '2p',
  39.     '3-Л': '3p',
  40.     'ИЗЪЯВ': 'real',
  41.     'ПОВ': 'imp',
  42.     'КР': 'shrt',
  43.     'НЕСОВ': 'imperf',
  44.     'СОВ': 'perf',
  45.     'СТРАД': 'pass',
  46.     'СЛ': 'compl',
  47.     'СМЯГ': 'soft',
  48.     'СРАВ': 'comp',
  49.     'ПРЕВ': 'supl',
  50. }
  51.  
  52. link_ru_en = {
  53.     'предик': 'subj',
  54.     '1-компл': 'obj',
  55.     '2-компл': 'obj',
  56.     '3-компл': 'obj',
  57.     '4-компл': 'obj',
  58.     '5-компл': 'obj',
  59.     'опред': 'amod',
  60.     'предл': 'prep',
  61.     'обст': 'pobj',
  62. }
  63. {
  64.     'огранич': '',      
  65.     'квазиагент': '',      
  66.     'сочин': '',      
  67.     'соч-союзн': '',      
  68.     'атриб': '',      
  69.     'аппоз': '',      
  70.     'подч-союзн': '',      
  71.     'вводн': '',      
  72.     'сент-соч': '',      
  73.     'количест': '',      
  74.     'разъяснит': '',      
  75.     'присвяз': '',      
  76.     'релят': '',      
  77.     'сравн-союзн': '',      
  78.     'примыкат': '',      
  79.     'сравнит': '',      
  80.     'соотнос': '',      
  81.     'эксплет': '',      
  82.     'аналит': '',      
  83.     'пасс-анал': '',      
  84.     'вспом': '',      
  85.     'агент': '',      
  86.     'кратн': '',      
  87.     'инф-союзн': '',      
  88.     'электив': '',      
  89.     'композ': '',      
  90.     'колич-огран': '',      
  91.     'неакт-компл': '',      
  92.     'пролепт': '',      
  93.     'суб-копр': '',      
  94.     'дат-субъект': '',      
  95.     'длительн': '',      
  96.     'об-аппоз': '',      
  97.     'изъясн': '',      
  98.     'компл-аппоз': '',      
  99.     'оп-опред': '',      
  100.     '1-несобст-компл': '',      
  101.     'распред': '',      
  102.     'уточн': '',      
  103.     'нум-аппоз': '',      
  104.     'ном-аппоз': '',      
  105.     '2-несобст-компл': '',      
  106.     'аппрокс-колич': '',      
  107.     'колич-вспом': '',      
  108.     'колич-копред': '',      
  109.     'кратно-длительн': '',      
  110.     'об-копр': '',      
  111.     'эллипт': '',      
  112.     '3-несобст-компл': '',      
  113.     '4-несобст-компл': '',      
  114.     'fictit': '',      
  115.     'авт-аппоз': '',      
  116.     'аддит': '',      
  117.     'адр-присв': '',      
  118.     'дистанц': '',      
  119.     'несобст-агент': '',      
  120.     'об-обст': '',      
  121.     'обст-тавт': '',      
  122.     'презентат': '',      
  123.     'сент-предик': '',      
  124.     'суб-обст': '',      
  125. }
  126.  
  127. class Reader:
  128.     def __init__(self):
  129.         self._parser = xml.parsers.expat.ParserCreate()
  130.         self._parser.StartElementHandler = self.start_element
  131.         self._parser.EndElementHandler = self.end_element
  132.         self._parser.CharacterDataHandler = self.char_data        
  133.    
  134.     def start_element(self, name, attr):
  135.         if name == 'W':
  136.             features = attr['FEAT'].split(' ') if 'FEAT' in attr else ['UNK']
  137.             for i in range(0, len(features)):
  138.                 if features[i] in feat_ru_en:
  139.                     features[i] = feat_ru_en[features[i]]
  140.                    
  141.             lemma = lemma=attr['LEMMA'].lower() if 'LEMMA' in attr else ''
  142.             link = attr['LINK'] if 'LINK' in attr else None
  143. #            if link in link_ru_en:
  144. #                link = link_ru_en[link]
  145.                
  146.             dom = int(attr['DOM']) if attr['DOM'] != '_root' else 0
  147.             pos = features[0]
  148.             feat = set(features[1:])
  149.            
  150.             if 'adjp' in feat:
  151.                 pos = 'VADJ'
  152.                 feat -= {'adjp'}
  153.                
  154.             if 'advp' in feat:
  155.                 pos = 'VADV'
  156.                 feat -= {'advp'}
  157.            
  158.             if 'inf' in feat:
  159.                 pos = 'VINF'
  160.                 feat -= {'inf'}
  161.            
  162.             self._info = word_t(lemma=lemma, pos=pos, feat=feat, id=int(attr['ID']), dom=dom, link=link)
  163.             self._cdata = ''
  164.    
  165.     def end_element(self, name):
  166.         if name == 'S':
  167.             self._sentences.append(self._sentence)
  168.             self._sentence = []
  169.         elif name == 'W':
  170.             self._sentence.append((self._cdata, self._info))
  171.             self._cdata = ''
  172.    
  173.     def char_data(self, content):
  174.         self._cdata += content
  175.        
  176.     def read(self, filename):
  177.         #f = open(filename, encoding='windows-1251')
  178.         f = open(filename, encoding='utf-8')
  179.         content = f.read()
  180.         f.close()
  181.         #content = content.replace('encoding="windows-1251"', 'encoding="utf-8"')
  182.        
  183.         self._sentences = []
  184.         self._sentence = []
  185.         self._cdata = ''
  186.         self._info = ''
  187.        
  188.         self._parser.Parse(content)
  189.        
  190.         return self._sentences
  191.  
  192. class Lexicon:
  193.     def __init__(self, dbname):
  194.         self.dbname = dbname
  195.         db_exists = os.path.isfile(dbname)
  196.         self.con = sqlite3.connect(dbname)
  197.         self.cur = self.con.cursor()
  198.        
  199.         if not db_exists:
  200.             self.create_db()        
  201.    
  202.     def create_db(self):
  203.         sql = '''
  204.        create table words(
  205.            id integer primary key autoincrement,
  206.            lemma text,
  207.            pos text,
  208.            form text,
  209.            info text,
  210.            freq integer
  211.        );
  212.        create index words_lemma_form_info on words(lemma, form, info);
  213.        '''
  214.         [self.cur.execute(st) for st in sql.split(';') if len(st.strip())]
  215.        
  216.     def index(self, filename):
  217.         sentences = Reader().read(filename)
  218.         for sentence in sentences:
  219.             for word in sentence:
  220.                 feat = ' '.join(word[1].feat)
  221.                 self.cur.execute('select id from words where lemma = ? and form = ? and pos = ? and info = ?', (word[1].lemma, word[0], word[1].pos, feat))
  222.                 row = self.cur.fetchone()
  223.                 if row is None:
  224.                     self.cur.execute('insert into words (lemma, pos, form, info, freq) values (?, ?, ?, ?, 1)', (word[1].lemma, word[1].pos, word[0], feat))
  225.                 else:
  226.                     self.cur.execute('update words set freq = freq + 1 where id = ?', row)
  227.                    
  228.     def close(self):
  229.         self.con.commit()
  230.         self.con.close()
  231.    
  232. if __name__ == '__main__':
  233.     parser = OptionParser()
  234.     parser.usage = '%prog [options] inputfile'
  235.     parser.add_option('-L', '--construct-lexicon', action = 'store_const', const = True, dest = 'lexicon', help = 'construct lexicon')
  236.  
  237.     (options, args) = parser.parse_args()
  238.    
  239.     if options.lexicon:
  240.         L = Lexicon('syntagrus/SynTagRus2019')
  241.         files = glob.glob('*/*.tgt')
  242.         for file in files:
  243.             L.index(file)
  244.        
  245.         L.close()
  246.  
  247.     R = Reader()
  248.     #sentences = R.read(args[0])
  249.     sentences = R.read('syntagrus/SynTagRus2019/2003/a_on_myatezhnyi.tgt')
  250.     print(len(sentences))
  251.     print(sentences[0])
Advertisement
Add Comment
Please, Sign In to add comment