mirror of
				https://github.com/explosion/spaCy.git
				synced 2025-11-04 01:48:04 +03:00 
			
		
		
		
	
						commit
						fcaa0ad7ce
					
				| 
						 | 
					@ -98,7 +98,7 @@ def _read_probs(loc):
 | 
				
			||||||
    return probs, probs['-OOV-']
 | 
					    return probs, probs['-OOV-']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _read_freqs(loc, max_length=100, min_doc_freq=5, min_freq=200):
 | 
					def _read_freqs(loc, max_length=100, min_doc_freq=0, min_freq=200):
 | 
				
			||||||
    if not loc.exists():
 | 
					    if not loc.exists():
 | 
				
			||||||
        print("Warning: Frequencies file not found")
 | 
					        print("Warning: Frequencies file not found")
 | 
				
			||||||
        return {}, 0.0
 | 
					        return {}, 0.0
 | 
				
			||||||
| 
						 | 
					@ -125,7 +125,8 @@ def _read_freqs(loc, max_length=100, min_doc_freq=5, min_freq=200):
 | 
				
			||||||
        doc_freq = int(doc_freq)
 | 
					        doc_freq = int(doc_freq)
 | 
				
			||||||
        freq = int(freq)
 | 
					        freq = int(freq)
 | 
				
			||||||
        if doc_freq >= min_doc_freq and freq >= min_freq and len(key) < max_length:
 | 
					        if doc_freq >= min_doc_freq and freq >= min_freq and len(key) < max_length:
 | 
				
			||||||
            word = literal_eval(key)
 | 
					#            word = literal_eval(key)
 | 
				
			||||||
 | 
					            word = key
 | 
				
			||||||
            smooth_count = counts.smoother(int(freq))
 | 
					            smooth_count = counts.smoother(int(freq))
 | 
				
			||||||
            log_smooth_count = math.log(smooth_count)
 | 
					            log_smooth_count = math.log(smooth_count)
 | 
				
			||||||
            probs[word] = math.log(smooth_count) - log_total
 | 
					            probs[word] = math.log(smooth_count) - log_total
 | 
				
			||||||
| 
						 | 
					@ -165,7 +166,7 @@ def setup_vocab(get_lex_attr, tag_map, src_dir, dst_dir):
 | 
				
			||||||
    clusters = _read_clusters(src_dir / 'clusters.txt')
 | 
					    clusters = _read_clusters(src_dir / 'clusters.txt')
 | 
				
			||||||
    probs, oov_prob = _read_probs(src_dir / 'words.sgt.prob')
 | 
					    probs, oov_prob = _read_probs(src_dir / 'words.sgt.prob')
 | 
				
			||||||
    if not probs:
 | 
					    if not probs:
 | 
				
			||||||
        probs, oov_prob = _read_freqs(src_dir / 'freqs.txt.gz')
 | 
					        probs, oov_prob = _read_freqs(src_dir / 'freqs.txt')
 | 
				
			||||||
    if not probs:
 | 
					    if not probs:
 | 
				
			||||||
        oov_prob = -20
 | 
					        oov_prob = -20
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
| 
						 | 
					@ -223,7 +224,6 @@ def main(lang_id, lang_data_dir, corpora_dir, model_dir):
 | 
				
			||||||
        copyfile(str(lang_data_dir / 'gazetteer.json'),
 | 
					        copyfile(str(lang_data_dir / 'gazetteer.json'),
 | 
				
			||||||
                 str(model_dir / 'vocab' / 'gazetteer.json'))
 | 
					                 str(model_dir / 'vocab' / 'gazetteer.json'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (lang_data_dir / 'tag_map.json').exists():
 | 
					 | 
				
			||||||
    copyfile(str(lang_data_dir / 'tag_map.json'),
 | 
					    copyfile(str(lang_data_dir / 'tag_map.json'),
 | 
				
			||||||
             str(model_dir / 'vocab' / 'tag_map.json'))
 | 
					             str(model_dir / 'vocab' / 'tag_map.json'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,7 @@ import re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import spacy.util
 | 
					import spacy.util
 | 
				
			||||||
from spacy.en import English
 | 
					from spacy.en import English
 | 
				
			||||||
 | 
					from spacy.de import German
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from spacy.syntax.util import Config
 | 
					from spacy.syntax.util import Config
 | 
				
			||||||
from spacy.gold import read_json_file
 | 
					from spacy.gold import read_json_file
 | 
				
			||||||
| 
						 | 
					@ -25,6 +26,7 @@ from spacy.syntax.arc_eager import ArcEager
 | 
				
			||||||
from spacy.syntax.ner import BiluoPushDown
 | 
					from spacy.syntax.ner import BiluoPushDown
 | 
				
			||||||
from spacy.tagger import Tagger
 | 
					from spacy.tagger import Tagger
 | 
				
			||||||
from spacy.syntax.parser import Parser
 | 
					from spacy.syntax.parser import Parser
 | 
				
			||||||
 | 
					from spacy.syntax.nonproj import PseudoProjectivity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _corrupt(c, noise_level):
 | 
					def _corrupt(c, noise_level):
 | 
				
			||||||
| 
						 | 
					@ -82,7 +84,7 @@ def _merge_sents(sents):
 | 
				
			||||||
def train(Language, gold_tuples, model_dir, n_iter=15, feat_set=u'basic',
 | 
					def train(Language, gold_tuples, model_dir, n_iter=15, feat_set=u'basic',
 | 
				
			||||||
          seed=0, gold_preproc=False, n_sents=0, corruption_level=0,
 | 
					          seed=0, gold_preproc=False, n_sents=0, corruption_level=0,
 | 
				
			||||||
          beam_width=1, verbose=False,
 | 
					          beam_width=1, verbose=False,
 | 
				
			||||||
          use_orig_arc_eager=False):
 | 
					          use_orig_arc_eager=False, pseudoprojective=False):
 | 
				
			||||||
    dep_model_dir = path.join(model_dir, 'deps')
 | 
					    dep_model_dir = path.join(model_dir, 'deps')
 | 
				
			||||||
    ner_model_dir = path.join(model_dir, 'ner')
 | 
					    ner_model_dir = path.join(model_dir, 'ner')
 | 
				
			||||||
    pos_model_dir = path.join(model_dir, 'pos')
 | 
					    pos_model_dir = path.join(model_dir, 'pos')
 | 
				
			||||||
| 
						 | 
					@ -96,9 +98,13 @@ def train(Language, gold_tuples, model_dir, n_iter=15, feat_set=u'basic',
 | 
				
			||||||
    os.mkdir(ner_model_dir)
 | 
					    os.mkdir(ner_model_dir)
 | 
				
			||||||
    os.mkdir(pos_model_dir)
 | 
					    os.mkdir(pos_model_dir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if pseudoprojective:
 | 
				
			||||||
 | 
					        # preprocess training data here before ArcEager.get_labels() is called
 | 
				
			||||||
 | 
					        gold_tuples = PseudoProjectivity.preprocess_training_data(gold_tuples)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Config.write(dep_model_dir, 'config', features=feat_set, seed=seed,
 | 
					    Config.write(dep_model_dir, 'config', features=feat_set, seed=seed,
 | 
				
			||||||
                 labels=ArcEager.get_labels(gold_tuples),
 | 
					                 labels=ArcEager.get_labels(gold_tuples),
 | 
				
			||||||
                 beam_width=beam_width)
 | 
					                 beam_width=beam_width,projectivize=pseudoprojective)
 | 
				
			||||||
    Config.write(ner_model_dir, 'config', features='ner', seed=seed,
 | 
					    Config.write(ner_model_dir, 'config', features='ner', seed=seed,
 | 
				
			||||||
                 labels=BiluoPushDown.get_labels(gold_tuples),
 | 
					                 labels=BiluoPushDown.get_labels(gold_tuples),
 | 
				
			||||||
                 beam_width=0)
 | 
					                 beam_width=0)
 | 
				
			||||||
| 
						 | 
					@ -107,6 +113,8 @@ def train(Language, gold_tuples, model_dir, n_iter=15, feat_set=u'basic',
 | 
				
			||||||
        gold_tuples = gold_tuples[:n_sents]
 | 
					        gold_tuples = gold_tuples[:n_sents]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    nlp = Language(data_dir=model_dir, tagger=False, parser=False, entity=False)
 | 
					    nlp = Language(data_dir=model_dir, tagger=False, parser=False, entity=False)
 | 
				
			||||||
 | 
					    if nlp.lang == 'de':
 | 
				
			||||||
 | 
					        nlp.vocab.morphology.lemmatizer = lambda string,pos: set([string])
 | 
				
			||||||
    nlp.tagger = Tagger.blank(nlp.vocab, Tagger.default_templates())
 | 
					    nlp.tagger = Tagger.blank(nlp.vocab, Tagger.default_templates())
 | 
				
			||||||
    nlp.parser = Parser.from_dir(dep_model_dir, nlp.vocab.strings, ArcEager)
 | 
					    nlp.parser = Parser.from_dir(dep_model_dir, nlp.vocab.strings, ArcEager)
 | 
				
			||||||
    nlp.entity = Parser.from_dir(ner_model_dir, nlp.vocab.strings, BiluoPushDown)
 | 
					    nlp.entity = Parser.from_dir(ner_model_dir, nlp.vocab.strings, BiluoPushDown)
 | 
				
			||||||
| 
						 | 
					@ -131,12 +139,9 @@ def train(Language, gold_tuples, model_dir, n_iter=15, feat_set=u'basic',
 | 
				
			||||||
                    raw_text = add_noise(raw_text, corruption_level)
 | 
					                    raw_text = add_noise(raw_text, corruption_level)
 | 
				
			||||||
                    tokens = nlp.tokenizer(raw_text)
 | 
					                    tokens = nlp.tokenizer(raw_text)
 | 
				
			||||||
                nlp.tagger(tokens)
 | 
					                nlp.tagger(tokens)
 | 
				
			||||||
                gold = GoldParse(tokens, annot_tuples, make_projective=True)
 | 
					                gold = GoldParse(tokens, annot_tuples)
 | 
				
			||||||
                if not gold.is_projective:
 | 
					                if not gold.is_projective:
 | 
				
			||||||
                    raise Exception(
 | 
					                    raise Exception("Non-projective sentence in training: %s" % annot_tuples)
 | 
				
			||||||
                        "Non-projective sentence in training, after we should "
 | 
					 | 
				
			||||||
                        "have enforced projectivity: %s" % annot_tuples
 | 
					 | 
				
			||||||
                    )
 | 
					 | 
				
			||||||
                loss += nlp.parser.train(tokens, gold)
 | 
					                loss += nlp.parser.train(tokens, gold)
 | 
				
			||||||
                nlp.entity.train(tokens, gold)
 | 
					                nlp.entity.train(tokens, gold)
 | 
				
			||||||
                nlp.tagger.train(tokens, gold.tags)
 | 
					                nlp.tagger.train(tokens, gold.tags)
 | 
				
			||||||
| 
						 | 
					@ -152,6 +157,8 @@ def train(Language, gold_tuples, model_dir, n_iter=15, feat_set=u'basic',
 | 
				
			||||||
def evaluate(Language, gold_tuples, model_dir, gold_preproc=False, verbose=False,
 | 
					def evaluate(Language, gold_tuples, model_dir, gold_preproc=False, verbose=False,
 | 
				
			||||||
             beam_width=None, cand_preproc=None):
 | 
					             beam_width=None, cand_preproc=None):
 | 
				
			||||||
    nlp = Language(data_dir=model_dir)
 | 
					    nlp = Language(data_dir=model_dir)
 | 
				
			||||||
 | 
					    if nlp.lang == 'de':
 | 
				
			||||||
 | 
					        nlp.vocab.morphology.lemmatizer = lambda string,pos: set([string])
 | 
				
			||||||
    if beam_width is not None:
 | 
					    if beam_width is not None:
 | 
				
			||||||
        nlp.parser.cfg.beam_width = beam_width
 | 
					        nlp.parser.cfg.beam_width = beam_width
 | 
				
			||||||
    scorer = Scorer()
 | 
					    scorer = Scorer()
 | 
				
			||||||
| 
						 | 
					@ -200,6 +207,7 @@ def write_parses(Language, dev_loc, model_dir, out_loc):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@plac.annotations(
 | 
					@plac.annotations(
 | 
				
			||||||
 | 
					    language=("The language to train", "positional", None, str, ['en','de']),
 | 
				
			||||||
    train_loc=("Location of training file or directory"),
 | 
					    train_loc=("Location of training file or directory"),
 | 
				
			||||||
    dev_loc=("Location of development file or directory"),
 | 
					    dev_loc=("Location of development file or directory"),
 | 
				
			||||||
    model_dir=("Location of output model directory",),
 | 
					    model_dir=("Location of output model directory",),
 | 
				
			||||||
| 
						 | 
					@ -211,19 +219,22 @@ def write_parses(Language, dev_loc, model_dir, out_loc):
 | 
				
			||||||
    n_iter=("Number of training iterations", "option", "i", int),
 | 
					    n_iter=("Number of training iterations", "option", "i", int),
 | 
				
			||||||
    verbose=("Verbose error reporting", "flag", "v", bool),
 | 
					    verbose=("Verbose error reporting", "flag", "v", bool),
 | 
				
			||||||
    debug=("Debug mode", "flag", "d", bool),
 | 
					    debug=("Debug mode", "flag", "d", bool),
 | 
				
			||||||
 | 
					    pseudoprojective=("Use pseudo-projective parsing", "flag", "p", bool),
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
def main(train_loc, dev_loc, model_dir, n_sents=0, n_iter=15, out_loc="", verbose=False,
 | 
					def main(language, train_loc, dev_loc, model_dir, n_sents=0, n_iter=15, out_loc="", verbose=False,
 | 
				
			||||||
         debug=False, corruption_level=0.0, gold_preproc=False, eval_only=False):
 | 
					         debug=False, corruption_level=0.0, gold_preproc=False, eval_only=False, pseudoprojective=False):
 | 
				
			||||||
 | 
					    lang = {'en':English, 'de':German}.get(language)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if not eval_only:
 | 
					    if not eval_only:
 | 
				
			||||||
        gold_train = list(read_json_file(train_loc))
 | 
					        gold_train = list(read_json_file(train_loc))
 | 
				
			||||||
        train(English, gold_train, model_dir,
 | 
					        train(lang, gold_train, model_dir,
 | 
				
			||||||
              feat_set='basic' if not debug else 'debug',
 | 
					              feat_set='basic' if not debug else 'debug',
 | 
				
			||||||
              gold_preproc=gold_preproc, n_sents=n_sents,
 | 
					              gold_preproc=gold_preproc, n_sents=n_sents,
 | 
				
			||||||
              corruption_level=corruption_level, n_iter=n_iter,
 | 
					              corruption_level=corruption_level, n_iter=n_iter,
 | 
				
			||||||
              verbose=verbose)
 | 
					              verbose=verbose,pseudoprojective=pseudoprojective)
 | 
				
			||||||
    if out_loc:
 | 
					    if out_loc:
 | 
				
			||||||
        write_parses(English, dev_loc, model_dir, out_loc)
 | 
					        write_parses(lang, dev_loc, model_dir, out_loc)
 | 
				
			||||||
    scorer = evaluate(English, list(read_json_file(dev_loc)),
 | 
					    scorer = evaluate(lang, list(read_json_file(dev_loc)),
 | 
				
			||||||
                      model_dir, gold_preproc=gold_preproc, verbose=verbose)
 | 
					                      model_dir, gold_preproc=gold_preproc, verbose=verbose)
 | 
				
			||||||
    print('TOK', scorer.token_acc)
 | 
					    print('TOK', scorer.token_acc)
 | 
				
			||||||
    print('POS', scorer.tags_acc)
 | 
					    print('POS', scorer.tags_acc)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										160
									
								
								bin/tagger/train_german_tagger.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								bin/tagger/train_german_tagger.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,160 @@
 | 
				
			||||||
 | 
					#!/usr/bin/env python
 | 
				
			||||||
 | 
					from __future__ import division
 | 
				
			||||||
 | 
					from __future__ import unicode_literals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					from os import path
 | 
				
			||||||
 | 
					import shutil
 | 
				
			||||||
 | 
					import io
 | 
				
			||||||
 | 
					import random
 | 
				
			||||||
 | 
					import time
 | 
				
			||||||
 | 
					import gzip
 | 
				
			||||||
 | 
					import ujson
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import plac
 | 
				
			||||||
 | 
					import cProfile
 | 
				
			||||||
 | 
					import pstats
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import spacy.util
 | 
				
			||||||
 | 
					from spacy.de import German
 | 
				
			||||||
 | 
					from spacy.gold import GoldParse
 | 
				
			||||||
 | 
					from spacy.tagger import Tagger
 | 
				
			||||||
 | 
					from spacy.scorer import PRFScore
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from spacy.tagger import P2_orth, P2_cluster, P2_shape, P2_prefix, P2_suffix, P2_pos, P2_lemma, P2_flags 
 | 
				
			||||||
 | 
					from spacy.tagger import P1_orth, P1_cluster, P1_shape, P1_prefix, P1_suffix, P1_pos, P1_lemma, P1_flags 
 | 
				
			||||||
 | 
					from spacy.tagger import W_orth, W_cluster, W_shape, W_prefix, W_suffix, W_pos, W_lemma, W_flags
 | 
				
			||||||
 | 
					from spacy.tagger import N1_orth, N1_cluster, N1_shape, N1_prefix, N1_suffix, N1_pos, N1_lemma, N1_flags
 | 
				
			||||||
 | 
					from spacy.tagger import N2_orth, N2_cluster, N2_shape, N2_prefix, N2_suffix, N2_pos, N2_lemma, N2_flags, N_CONTEXT_FIELDS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def default_templates():
 | 
				
			||||||
 | 
					    return spacy.tagger.Tagger.default_templates()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def default_templates_without_clusters():
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        (W_orth,),
 | 
				
			||||||
 | 
					        (P1_lemma, P1_pos),
 | 
				
			||||||
 | 
					        (P2_lemma, P2_pos),
 | 
				
			||||||
 | 
					        (N1_orth,),
 | 
				
			||||||
 | 
					        (N2_orth,),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        (W_suffix,),
 | 
				
			||||||
 | 
					        (W_prefix,),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        (P1_pos,),
 | 
				
			||||||
 | 
					        (P2_pos,),
 | 
				
			||||||
 | 
					        (P1_pos, P2_pos),
 | 
				
			||||||
 | 
					        (P1_pos, W_orth),
 | 
				
			||||||
 | 
					        (P1_suffix,),
 | 
				
			||||||
 | 
					        (N1_suffix,),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        (W_shape,),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        (W_flags,),
 | 
				
			||||||
 | 
					        (N1_flags,),
 | 
				
			||||||
 | 
					        (N2_flags,),
 | 
				
			||||||
 | 
					        (P1_flags,),
 | 
				
			||||||
 | 
					        (P2_flags,),
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def make_tagger(vocab, templates):
 | 
				
			||||||
 | 
					    model = spacy.tagger.TaggerModel(templates)
 | 
				
			||||||
 | 
					    return spacy.tagger.Tagger(vocab,model)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def read_conll(file_):
 | 
				
			||||||
 | 
					    def sentences():
 | 
				
			||||||
 | 
					        words, tags = [], []
 | 
				
			||||||
 | 
					        for line in file_:
 | 
				
			||||||
 | 
					            line = line.strip()
 | 
				
			||||||
 | 
					            if line:
 | 
				
			||||||
 | 
					                word, tag = line.split('\t')[1::3][:2] # get column 1 and 4 (CoNLL09)
 | 
				
			||||||
 | 
					                words.append(word)
 | 
				
			||||||
 | 
					                tags.append(tag)
 | 
				
			||||||
 | 
					            elif words:
 | 
				
			||||||
 | 
					                yield words, tags
 | 
				
			||||||
 | 
					                words, tags = [], []
 | 
				
			||||||
 | 
					        if words:
 | 
				
			||||||
 | 
					            yield words, tags
 | 
				
			||||||
 | 
					    return [ s for s in sentences() ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					def score_model(score, nlp, words, gold_tags):
 | 
				
			||||||
 | 
					    tokens = nlp.tokenizer.tokens_from_list(words)
 | 
				
			||||||
 | 
					    assert(len(tokens) == len(gold_tags))
 | 
				
			||||||
 | 
					    nlp.tagger(tokens)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for token, gold_tag in zip(tokens,gold_tags):
 | 
				
			||||||
 | 
					        score.score_set(set([token.tag_]),set([gold_tag]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def train(Language, train_sents, dev_sents, model_dir, n_iter=15, seed=21):
 | 
				
			||||||
 | 
					    # make shuffling deterministic
 | 
				
			||||||
 | 
					    random.seed(seed)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # set up directory for model
 | 
				
			||||||
 | 
					    pos_model_dir = path.join(model_dir, 'pos')
 | 
				
			||||||
 | 
					    if path.exists(pos_model_dir):
 | 
				
			||||||
 | 
					        shutil.rmtree(pos_model_dir)
 | 
				
			||||||
 | 
					    os.mkdir(pos_model_dir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    nlp = Language(data_dir=model_dir, tagger=False, parser=False, entity=False)
 | 
				
			||||||
 | 
					    nlp.tagger = make_tagger(nlp.vocab,default_templates())
 | 
				
			||||||
 | 
					     
 | 
				
			||||||
 | 
					    print("Itn.\ttrain acc %\tdev acc %")
 | 
				
			||||||
 | 
					    for itn in range(n_iter):
 | 
				
			||||||
 | 
					        # train on train set
 | 
				
			||||||
 | 
					        #train_acc = PRFScore()
 | 
				
			||||||
 | 
					        correct, total = 0., 0.
 | 
				
			||||||
 | 
					        for words, gold_tags in train_sents:
 | 
				
			||||||
 | 
					            tokens = nlp.tokenizer.tokens_from_list(words)
 | 
				
			||||||
 | 
					            correct += nlp.tagger.train(tokens, gold_tags)
 | 
				
			||||||
 | 
					            total += len(words)
 | 
				
			||||||
 | 
					        train_acc = correct/total
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # test on dev set
 | 
				
			||||||
 | 
					        dev_acc = PRFScore()
 | 
				
			||||||
 | 
					        for words, gold_tags in dev_sents:
 | 
				
			||||||
 | 
					            score_model(dev_acc, nlp, words, gold_tags)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        random.shuffle(train_sents)
 | 
				
			||||||
 | 
					        print('%d:\t%6.2f\t%6.2f' % (itn, 100*train_acc, 100*dev_acc.precision))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    print('end training')
 | 
				
			||||||
 | 
					    nlp.end_training(model_dir)
 | 
				
			||||||
 | 
					    print('done')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@plac.annotations(
 | 
				
			||||||
 | 
					    train_loc=("Location of CoNLL 09 formatted training file"),
 | 
				
			||||||
 | 
					    dev_loc=("Location of CoNLL 09 formatted development file"),
 | 
				
			||||||
 | 
					    model_dir=("Location of output model directory"),
 | 
				
			||||||
 | 
					    eval_only=("Skip training, and only evaluate", "flag", "e", bool),
 | 
				
			||||||
 | 
					    n_iter=("Number of training iterations", "option", "i", int),
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					def main(train_loc, dev_loc, model_dir, eval_only=False, n_iter=15):
 | 
				
			||||||
 | 
					    # training
 | 
				
			||||||
 | 
					    if not eval_only:
 | 
				
			||||||
 | 
					        with io.open(train_loc, 'r', encoding='utf8') as trainfile_, \
 | 
				
			||||||
 | 
					             io.open(dev_loc, 'r', encoding='utf8') as devfile_:
 | 
				
			||||||
 | 
					            train_sents = read_conll(trainfile_)
 | 
				
			||||||
 | 
					            dev_sents = read_conll(devfile_)
 | 
				
			||||||
 | 
					        train(German, train_sents, dev_sents, model_dir, n_iter=n_iter)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # testing
 | 
				
			||||||
 | 
					    with io.open(dev_loc, 'r', encoding='utf8') as file_:
 | 
				
			||||||
 | 
					        dev_sents = read_conll(file_)
 | 
				
			||||||
 | 
					        nlp = German(data_dir=model_dir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dev_acc = PRFScore()
 | 
				
			||||||
 | 
					        for words, gold_tags in dev_sents:
 | 
				
			||||||
 | 
					            score_model(dev_acc, nlp, words, gold_tags)                
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        print('POS: %6.2f %%' % (100*dev_acc.precision))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    plac.call(main)
 | 
				
			||||||
							
								
								
									
										319
									
								
								lang_data/de/abbrev.de.tab
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										319
									
								
								lang_data/de/abbrev.de.tab
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,319 @@
 | 
				
			||||||
 | 
					# surface form lemma pos 
 | 
				
			||||||
 | 
					# multiple values are separated by |
 | 
				
			||||||
 | 
					# empty lines and lines starting with # are being ignored 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					''	''
 | 
				
			||||||
 | 
					\")	\")
 | 
				
			||||||
 | 
					\n	\n	<nl>	SP
 | 
				
			||||||
 | 
					\t	\t	<tab>	SP
 | 
				
			||||||
 | 
					 	 	<space>	SP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# example: Wie geht's?
 | 
				
			||||||
 | 
					's	's	es
 | 
				
			||||||
 | 
					'S	'S	es
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# example: Haste mal 'nen Euro?
 | 
				
			||||||
 | 
					'n	'n	ein
 | 
				
			||||||
 | 
					'ne	'ne	eine
 | 
				
			||||||
 | 
					'nen	'nen	einen
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# example: Kommen S’ nur herein!
 | 
				
			||||||
 | 
					s'	s'	sie
 | 
				
			||||||
 | 
					S'	S'	sie
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# example: Da haben wir's!
 | 
				
			||||||
 | 
					ich's	ich|'s	ich|es
 | 
				
			||||||
 | 
					du's	du|'s	du|es
 | 
				
			||||||
 | 
					er's	er|'s	er|es
 | 
				
			||||||
 | 
					sie's	sie|'s	sie|es
 | 
				
			||||||
 | 
					wir's	wir|'s	wir|es
 | 
				
			||||||
 | 
					ihr's	ihr|'s	ihr|es
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# example: Die katze auf'm dach.
 | 
				
			||||||
 | 
					auf'm	auf|'m	auf|dem
 | 
				
			||||||
 | 
					unter'm	unter|'m	unter|dem
 | 
				
			||||||
 | 
					über'm	über|'m	über|dem
 | 
				
			||||||
 | 
					vor'm	vor|'m	vor|dem
 | 
				
			||||||
 | 
					hinter'm	hinter|'m	hinter|dem
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# persons
 | 
				
			||||||
 | 
					B.A.	B.A.
 | 
				
			||||||
 | 
					B.Sc.	B.Sc.
 | 
				
			||||||
 | 
					Dipl.	Dipl.
 | 
				
			||||||
 | 
					Dipl.-Ing.	Dipl.-Ing.
 | 
				
			||||||
 | 
					Dr.	Dr.
 | 
				
			||||||
 | 
					Fr.	Fr.
 | 
				
			||||||
 | 
					Frl.	Frl.
 | 
				
			||||||
 | 
					Hr.	Hr.
 | 
				
			||||||
 | 
					Hrn.	Hrn.
 | 
				
			||||||
 | 
					Frl.	Frl.
 | 
				
			||||||
 | 
					Prof.	Prof.
 | 
				
			||||||
 | 
					St.	St.
 | 
				
			||||||
 | 
					Hrgs.	Hrgs.
 | 
				
			||||||
 | 
					Hg.	Hg.
 | 
				
			||||||
 | 
					a.Z.	a.Z.
 | 
				
			||||||
 | 
					a.D.	a.D.
 | 
				
			||||||
 | 
					h.c.	h.c.
 | 
				
			||||||
 | 
					Jr.	Jr.
 | 
				
			||||||
 | 
					jr.	jr.
 | 
				
			||||||
 | 
					jun.	jun.
 | 
				
			||||||
 | 
					sen.	sen.
 | 
				
			||||||
 | 
					rer.	rer.
 | 
				
			||||||
 | 
					Ing.	Ing.
 | 
				
			||||||
 | 
					M.A.	M.A.
 | 
				
			||||||
 | 
					Mr.	Mr.
 | 
				
			||||||
 | 
					M.Sc.	M.Sc.
 | 
				
			||||||
 | 
					nat.	nat.
 | 
				
			||||||
 | 
					phil.	phil.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# companies
 | 
				
			||||||
 | 
					Co.	Co.
 | 
				
			||||||
 | 
					co.	co.
 | 
				
			||||||
 | 
					Cie.	Cie.
 | 
				
			||||||
 | 
					A.G.	A.G.
 | 
				
			||||||
 | 
					G.m.b.H.	G.m.b.H.
 | 
				
			||||||
 | 
					i.G.	i.G.
 | 
				
			||||||
 | 
					e.V.	e.V.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# popular german abbreviations
 | 
				
			||||||
 | 
					Abb.	Abb.
 | 
				
			||||||
 | 
					Abk.	Abk.
 | 
				
			||||||
 | 
					Abs.	Abs.
 | 
				
			||||||
 | 
					Abt.	Abt.
 | 
				
			||||||
 | 
					abzgl.	abzgl.
 | 
				
			||||||
 | 
					allg.	allg.
 | 
				
			||||||
 | 
					a.M.	a.M.
 | 
				
			||||||
 | 
					Bd.	Bd.
 | 
				
			||||||
 | 
					betr.	betr.
 | 
				
			||||||
 | 
					Betr.	Betr.
 | 
				
			||||||
 | 
					Biol.	Biol.
 | 
				
			||||||
 | 
					biol.	biol.
 | 
				
			||||||
 | 
					Bf.	Bf.
 | 
				
			||||||
 | 
					Bhf.	Bhf.
 | 
				
			||||||
 | 
					Bsp.	Bsp.
 | 
				
			||||||
 | 
					bspw.	bspw.
 | 
				
			||||||
 | 
					bzgl.	bzgl.
 | 
				
			||||||
 | 
					bzw.	bzw.
 | 
				
			||||||
 | 
					d.h.	d.h.
 | 
				
			||||||
 | 
					dgl.	dgl.
 | 
				
			||||||
 | 
					ebd.	ebd.
 | 
				
			||||||
 | 
					ehem.	ehem.
 | 
				
			||||||
 | 
					eigtl.	eigtl.
 | 
				
			||||||
 | 
					entspr.	entspr.
 | 
				
			||||||
 | 
					erm.	erm.
 | 
				
			||||||
 | 
					ev.	ev.
 | 
				
			||||||
 | 
					evtl.	evtl.
 | 
				
			||||||
 | 
					Fa.	Fa.
 | 
				
			||||||
 | 
					Fam.	Fam.
 | 
				
			||||||
 | 
					geb.	geb.
 | 
				
			||||||
 | 
					Gebr.	Gebr.
 | 
				
			||||||
 | 
					gem.	gem.
 | 
				
			||||||
 | 
					ggf.	ggf.
 | 
				
			||||||
 | 
					ggü.	ggü.
 | 
				
			||||||
 | 
					ggfs.	ggfs.
 | 
				
			||||||
 | 
					gegr.	gegr.
 | 
				
			||||||
 | 
					Hbf.	Hbf.
 | 
				
			||||||
 | 
					Hrsg.	Hrsg.
 | 
				
			||||||
 | 
					hrsg.	hrsg.
 | 
				
			||||||
 | 
					i.A.	i.A.
 | 
				
			||||||
 | 
					i.d.R.	i.d.R.
 | 
				
			||||||
 | 
					inkl.	inkl.
 | 
				
			||||||
 | 
					insb.	insb.
 | 
				
			||||||
 | 
					i.O.	i.O.
 | 
				
			||||||
 | 
					i.Tr.	i.Tr.
 | 
				
			||||||
 | 
					i.V.	i.V.
 | 
				
			||||||
 | 
					jur.	jur.
 | 
				
			||||||
 | 
					kath.	kath.
 | 
				
			||||||
 | 
					K.O.	K.O.
 | 
				
			||||||
 | 
					lt.	lt.
 | 
				
			||||||
 | 
					max.	max.
 | 
				
			||||||
 | 
					m.E.	m.E.
 | 
				
			||||||
 | 
					m.M.	m.M.
 | 
				
			||||||
 | 
					mtl.	mtl.
 | 
				
			||||||
 | 
					min.	min.
 | 
				
			||||||
 | 
					mind.	mind.
 | 
				
			||||||
 | 
					MwSt.	MwSt.
 | 
				
			||||||
 | 
					Nr.	Nr.
 | 
				
			||||||
 | 
					o.a.	o.a.
 | 
				
			||||||
 | 
					o.ä.	o.ä.
 | 
				
			||||||
 | 
					o.Ä.	o.Ä.
 | 
				
			||||||
 | 
					o.g.	o.g.
 | 
				
			||||||
 | 
					o.k.	o.k.
 | 
				
			||||||
 | 
					O.K.	O.K.
 | 
				
			||||||
 | 
					Orig.	Orig.
 | 
				
			||||||
 | 
					orig.	orig.
 | 
				
			||||||
 | 
					pers.	pers.
 | 
				
			||||||
 | 
					Pkt.	Pkt.
 | 
				
			||||||
 | 
					Red.	Red.
 | 
				
			||||||
 | 
					röm.	röm.
 | 
				
			||||||
 | 
					s.o.	s.o.
 | 
				
			||||||
 | 
					sog.	sog.
 | 
				
			||||||
 | 
					std.	std.
 | 
				
			||||||
 | 
					stellv.	stellv.
 | 
				
			||||||
 | 
					Str.	Str.
 | 
				
			||||||
 | 
					tägl.	tägl.
 | 
				
			||||||
 | 
					Tel.	Tel.
 | 
				
			||||||
 | 
					u.a.	u.a.
 | 
				
			||||||
 | 
					usf.	usf.
 | 
				
			||||||
 | 
					u.s.w.	u.s.w.
 | 
				
			||||||
 | 
					usw.	usw.
 | 
				
			||||||
 | 
					u.U.	u.U.
 | 
				
			||||||
 | 
					u.v.m.	u.v.m.
 | 
				
			||||||
 | 
					uvm.	uvm.
 | 
				
			||||||
 | 
					v.a.	v.a.
 | 
				
			||||||
 | 
					vgl.	vgl.
 | 
				
			||||||
 | 
					vllt.	vllt.
 | 
				
			||||||
 | 
					v.l.n.r.	v.l.n.r.
 | 
				
			||||||
 | 
					vlt.	vlt.
 | 
				
			||||||
 | 
					Vol.	Vol.
 | 
				
			||||||
 | 
					wiss.	wiss.
 | 
				
			||||||
 | 
					Univ.	Univ.
 | 
				
			||||||
 | 
					z.B.	z.B.
 | 
				
			||||||
 | 
					z.b.	z.b.
 | 
				
			||||||
 | 
					z.Bsp.	z.Bsp.
 | 
				
			||||||
 | 
					z.T.	z.T.
 | 
				
			||||||
 | 
					z.Z.	z.Z.
 | 
				
			||||||
 | 
					zzgl.	zzgl.
 | 
				
			||||||
 | 
					z.Zt.	z.Zt.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# popular latin abbreviations
 | 
				
			||||||
 | 
					vs.	vs.
 | 
				
			||||||
 | 
					adv.	adv.
 | 
				
			||||||
 | 
					Chr.	Chr.
 | 
				
			||||||
 | 
					A.C.	A.C.
 | 
				
			||||||
 | 
					A.D.	A.D.
 | 
				
			||||||
 | 
					e.g.	e.g.
 | 
				
			||||||
 | 
					i.e.	i.e.
 | 
				
			||||||
 | 
					al.	al.
 | 
				
			||||||
 | 
					p.a.	p.a.
 | 
				
			||||||
 | 
					P.S.	P.S.
 | 
				
			||||||
 | 
					q.e.d.	q.e.d.
 | 
				
			||||||
 | 
					R.I.P.	R.I.P.
 | 
				
			||||||
 | 
					etc.	etc.
 | 
				
			||||||
 | 
					incl.	incl.
 | 
				
			||||||
 | 
					ca.	ca.
 | 
				
			||||||
 | 
					n.Chr.	n.Chr.
 | 
				
			||||||
 | 
					p.s.	p.s.
 | 
				
			||||||
 | 
					v.Chr.	v.Chr.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# popular english abbreviations
 | 
				
			||||||
 | 
					D.C.	D.C.
 | 
				
			||||||
 | 
					N.Y.	N.Y.
 | 
				
			||||||
 | 
					N.Y.C.	N.Y.C.
 | 
				
			||||||
 | 
					U.S.	U.S.
 | 
				
			||||||
 | 
					U.S.A.	U.S.A.
 | 
				
			||||||
 | 
					L.A.	L.A.
 | 
				
			||||||
 | 
					U.S.S.	U.S.S.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# dates & time
 | 
				
			||||||
 | 
					Jan.	Jan.
 | 
				
			||||||
 | 
					Feb.	Feb.
 | 
				
			||||||
 | 
					Mrz.	Mrz.
 | 
				
			||||||
 | 
					Mär.	Mär.
 | 
				
			||||||
 | 
					Apr.	Apr.
 | 
				
			||||||
 | 
					Jun.	Jun.
 | 
				
			||||||
 | 
					Jul.	Jul.
 | 
				
			||||||
 | 
					Aug.	Aug.
 | 
				
			||||||
 | 
					Sep.	Sep.
 | 
				
			||||||
 | 
					Sept.	Sept.
 | 
				
			||||||
 | 
					Okt.	Okt.
 | 
				
			||||||
 | 
					Nov.	Nov.
 | 
				
			||||||
 | 
					Dez.	Dez.
 | 
				
			||||||
 | 
					Mo.	Mo.
 | 
				
			||||||
 | 
					Di.	Di.
 | 
				
			||||||
 | 
					Mi.	Mi.
 | 
				
			||||||
 | 
					Do.	Do.
 | 
				
			||||||
 | 
					Fr.	Fr.
 | 
				
			||||||
 | 
					Sa.	Sa.
 | 
				
			||||||
 | 
					So.	So.
 | 
				
			||||||
 | 
					Std.	Std.
 | 
				
			||||||
 | 
					Jh.	Jh.
 | 
				
			||||||
 | 
					Jhd.	Jhd.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# numbers
 | 
				
			||||||
 | 
					Tsd.	Tsd.
 | 
				
			||||||
 | 
					Mio.	Mio.
 | 
				
			||||||
 | 
					Mrd.	Mrd.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# countries & languages
 | 
				
			||||||
 | 
					engl.	engl.
 | 
				
			||||||
 | 
					frz.	frz.
 | 
				
			||||||
 | 
					lat.	lat.
 | 
				
			||||||
 | 
					österr.	österr.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# smileys
 | 
				
			||||||
 | 
					:)	:)
 | 
				
			||||||
 | 
					<3	<3
 | 
				
			||||||
 | 
					;)	;)
 | 
				
			||||||
 | 
					(:	(:
 | 
				
			||||||
 | 
					:(	:(
 | 
				
			||||||
 | 
					-_-	-_-
 | 
				
			||||||
 | 
					=)	=)
 | 
				
			||||||
 | 
					:/	:/
 | 
				
			||||||
 | 
					:>	:>
 | 
				
			||||||
 | 
					;-)	;-)
 | 
				
			||||||
 | 
					:Y	:Y
 | 
				
			||||||
 | 
					:P	:P
 | 
				
			||||||
 | 
					:-P	:-P
 | 
				
			||||||
 | 
					:3	:3
 | 
				
			||||||
 | 
					=3	=3
 | 
				
			||||||
 | 
					xD	xD
 | 
				
			||||||
 | 
					^_^	^_^
 | 
				
			||||||
 | 
					=]	=]
 | 
				
			||||||
 | 
					=D	=D
 | 
				
			||||||
 | 
					<333	<333
 | 
				
			||||||
 | 
					:))	:))
 | 
				
			||||||
 | 
					:0	:0
 | 
				
			||||||
 | 
					-__-	-__-
 | 
				
			||||||
 | 
					xDD	xDD
 | 
				
			||||||
 | 
					o_o	o_o
 | 
				
			||||||
 | 
					o_O	o_O
 | 
				
			||||||
 | 
					V_V	V_V
 | 
				
			||||||
 | 
					=[[	=[[
 | 
				
			||||||
 | 
					<33	<33
 | 
				
			||||||
 | 
					;p	;p
 | 
				
			||||||
 | 
					;D	;D
 | 
				
			||||||
 | 
					;-p	;-p
 | 
				
			||||||
 | 
					;(	;(
 | 
				
			||||||
 | 
					:p	:p
 | 
				
			||||||
 | 
					:]	:]
 | 
				
			||||||
 | 
					:O	:O
 | 
				
			||||||
 | 
					:-/	:-/
 | 
				
			||||||
 | 
					:-)	:-)
 | 
				
			||||||
 | 
					:(((	:(((
 | 
				
			||||||
 | 
					:((	:((
 | 
				
			||||||
 | 
					:')	:')
 | 
				
			||||||
 | 
					(^_^)	(^_^)
 | 
				
			||||||
 | 
					(=	(=
 | 
				
			||||||
 | 
					o.O	o.O
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# single letters
 | 
				
			||||||
 | 
					a.	a.
 | 
				
			||||||
 | 
					b.	b.
 | 
				
			||||||
 | 
					c.	c.
 | 
				
			||||||
 | 
					d.	d.
 | 
				
			||||||
 | 
					e.	e.
 | 
				
			||||||
 | 
					f.	f.
 | 
				
			||||||
 | 
					g.	g.
 | 
				
			||||||
 | 
					h.	h.
 | 
				
			||||||
 | 
					i.	i.
 | 
				
			||||||
 | 
					j.	j.
 | 
				
			||||||
 | 
					k.	k.
 | 
				
			||||||
 | 
					l.	l.
 | 
				
			||||||
 | 
					m.	m.
 | 
				
			||||||
 | 
					n.	n.
 | 
				
			||||||
 | 
					o.	o.
 | 
				
			||||||
 | 
					p.	p.
 | 
				
			||||||
 | 
					q.	q.
 | 
				
			||||||
 | 
					r.	r.
 | 
				
			||||||
 | 
					s.	s.
 | 
				
			||||||
 | 
					t.	t.
 | 
				
			||||||
 | 
					u.	u.
 | 
				
			||||||
 | 
					v.	v.
 | 
				
			||||||
 | 
					w.	w.
 | 
				
			||||||
 | 
					x.	x.
 | 
				
			||||||
 | 
					y.	y.
 | 
				
			||||||
 | 
					z.	z.
 | 
				
			||||||
 | 
					ä.	ä.
 | 
				
			||||||
 | 
					ö.	ö.
 | 
				
			||||||
 | 
					ü.	ü.
 | 
				
			||||||
							
								
								
									
										194
									
								
								lang_data/de/gazetteer.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								lang_data/de/gazetteer.json
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,194 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						"Reddit": [
 | 
				
			||||||
 | 
							"PRODUCT",
 | 
				
			||||||
 | 
							{},
 | 
				
			||||||
 | 
							[
 | 
				
			||||||
 | 
								[{"lower": "reddit"}]
 | 
				
			||||||
 | 
							]
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
 | 
						"SeptemberElevenAttacks": [
 | 
				
			||||||
 | 
							"EVENT",
 | 
				
			||||||
 | 
							{},
 | 
				
			||||||
 | 
							[
 | 
				
			||||||
 | 
								[
 | 
				
			||||||
 | 
									{"orth": "9/11"}
 | 
				
			||||||
 | 
								],
 | 
				
			||||||
 | 
								[
 | 
				
			||||||
 | 
									{"lower": "september"},
 | 
				
			||||||
 | 
									{"orth": "11"}
 | 
				
			||||||
 | 
								]
 | 
				
			||||||
 | 
							]
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
 | 
						"Linux": [
 | 
				
			||||||
 | 
							"PRODUCT",
 | 
				
			||||||
 | 
							{},
 | 
				
			||||||
 | 
							[
 | 
				
			||||||
 | 
								[{"lower": "linux"}]
 | 
				
			||||||
 | 
							]
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
 | 
						"Haskell": [
 | 
				
			||||||
 | 
							"PRODUCT",
 | 
				
			||||||
 | 
							{},
 | 
				
			||||||
 | 
							[
 | 
				
			||||||
 | 
								[{"lower": "haskell"}]
 | 
				
			||||||
 | 
							]
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
 | 
						"HaskellCurry": [
 | 
				
			||||||
 | 
							"PERSON",
 | 
				
			||||||
 | 
							{},
 | 
				
			||||||
 | 
							[
 | 
				
			||||||
 | 
								[
 | 
				
			||||||
 | 
									{"lower": "haskell"},
 | 
				
			||||||
 | 
									{"lower": "curry"}
 | 
				
			||||||
 | 
								]
 | 
				
			||||||
 | 
							]
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
 | 
						"Javascript": [
 | 
				
			||||||
 | 
							"PRODUCT",
 | 
				
			||||||
 | 
							{},
 | 
				
			||||||
 | 
							[
 | 
				
			||||||
 | 
								[{"lower": "javascript"}]
 | 
				
			||||||
 | 
							]
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
 | 
						"CSS": [
 | 
				
			||||||
 | 
							"PRODUCT",
 | 
				
			||||||
 | 
							{},
 | 
				
			||||||
 | 
							[
 | 
				
			||||||
 | 
								[{"lower": "css"}],
 | 
				
			||||||
 | 
								[{"lower": "css3"}]
 | 
				
			||||||
 | 
							]
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
 | 
						"displaCy": [
 | 
				
			||||||
 | 
							"PRODUCT",
 | 
				
			||||||
 | 
							{},
 | 
				
			||||||
 | 
							[
 | 
				
			||||||
 | 
								[{"lower": "displacy"}]
 | 
				
			||||||
 | 
							]
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
 | 
						"spaCy": [
 | 
				
			||||||
 | 
							"PRODUCT",
 | 
				
			||||||
 | 
							{},
 | 
				
			||||||
 | 
							[
 | 
				
			||||||
 | 
								[{"orth": "spaCy"}]
 | 
				
			||||||
 | 
							]
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "HTML": [
 | 
				
			||||||
 | 
							"PRODUCT",
 | 
				
			||||||
 | 
							{},
 | 
				
			||||||
 | 
							[
 | 
				
			||||||
 | 
								[{"lower": "html"}],
 | 
				
			||||||
 | 
								[{"lower": "html5"}]
 | 
				
			||||||
 | 
							]
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
 | 
					    "Python": [
 | 
				
			||||||
 | 
					        "PRODUCT",
 | 
				
			||||||
 | 
					        {},
 | 
				
			||||||
 | 
					        [
 | 
				
			||||||
 | 
					            [{"orth": "Python"}]
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "Ruby": [
 | 
				
			||||||
 | 
					        "PRODUCT",
 | 
				
			||||||
 | 
					        {},
 | 
				
			||||||
 | 
					        [
 | 
				
			||||||
 | 
					            [{"orth": "Ruby"}]
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "Digg": [
 | 
				
			||||||
 | 
					        "PRODUCT",
 | 
				
			||||||
 | 
					        {},
 | 
				
			||||||
 | 
					        [
 | 
				
			||||||
 | 
					            [{"lower": "digg"}]
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					     "FoxNews": [
 | 
				
			||||||
 | 
					        "ORG",
 | 
				
			||||||
 | 
					        {},
 | 
				
			||||||
 | 
					        [
 | 
				
			||||||
 | 
					            [{"orth": "Fox"}],
 | 
				
			||||||
 | 
					            [{"orth": "News"}]
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "Google": [
 | 
				
			||||||
 | 
					        "ORG",
 | 
				
			||||||
 | 
					        {},
 | 
				
			||||||
 | 
					        [
 | 
				
			||||||
 | 
					            [{"lower": "google"}]
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "Mac": [
 | 
				
			||||||
 | 
					        "PRODUCT",
 | 
				
			||||||
 | 
					        {},
 | 
				
			||||||
 | 
					        [
 | 
				
			||||||
 | 
					            [{"lower": "mac"}]
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "Wikipedia": [
 | 
				
			||||||
 | 
					        "PRODUCT",
 | 
				
			||||||
 | 
					        {},
 | 
				
			||||||
 | 
					        [
 | 
				
			||||||
 | 
					            [{"lower": "wikipedia"}]
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "Windows": [
 | 
				
			||||||
 | 
					        "PRODUCT",
 | 
				
			||||||
 | 
					        {},
 | 
				
			||||||
 | 
					        [
 | 
				
			||||||
 | 
					            [{"orth": "Windows"}]
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					     "Dell": [
 | 
				
			||||||
 | 
					        "ORG",
 | 
				
			||||||
 | 
					        {},
 | 
				
			||||||
 | 
					        [
 | 
				
			||||||
 | 
					            [{"lower": "dell"}]
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "Facebook": [
 | 
				
			||||||
 | 
					        "ORG",
 | 
				
			||||||
 | 
					        {},
 | 
				
			||||||
 | 
					        [
 | 
				
			||||||
 | 
					            [{"lower": "facebook"}]
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					     "Blizzard": [
 | 
				
			||||||
 | 
					        "ORG",
 | 
				
			||||||
 | 
					        {},
 | 
				
			||||||
 | 
					        [
 | 
				
			||||||
 | 
					            [{"orth": "Blizzard"}]
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "Ubuntu": [
 | 
				
			||||||
 | 
					        "ORG",
 | 
				
			||||||
 | 
					        {},
 | 
				
			||||||
 | 
					        [
 | 
				
			||||||
 | 
					            [{"orth": "Ubuntu"}]
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "Youtube": [
 | 
				
			||||||
 | 
					        "PRODUCT",
 | 
				
			||||||
 | 
					        {},
 | 
				
			||||||
 | 
					        [
 | 
				
			||||||
 | 
					            [{"lower": "youtube"}]
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "false_positives": [
 | 
				
			||||||
 | 
					        null,
 | 
				
			||||||
 | 
					        {},
 | 
				
			||||||
 | 
					        [
 | 
				
			||||||
 | 
					            [{"orth": "Shit"}],
 | 
				
			||||||
 | 
					            [{"orth": "Weed"}],
 | 
				
			||||||
 | 
					            [{"orth": "Cool"}],
 | 
				
			||||||
 | 
					            [{"orth": "Btw"}],
 | 
				
			||||||
 | 
					            [{"orth": "Bah"}],
 | 
				
			||||||
 | 
					            [{"orth": "Bullshit"}],
 | 
				
			||||||
 | 
					            [{"orth": "Lol"}],
 | 
				
			||||||
 | 
					            [{"orth": "Yo"}, {"lower": "dawg"}],
 | 
				
			||||||
 | 
					            [{"orth": "Yay"}],
 | 
				
			||||||
 | 
					            [{"orth": "Ahh"}],
 | 
				
			||||||
 | 
					            [{"orth": "Yea"}],
 | 
				
			||||||
 | 
					            [{"orth": "Bah"}]
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,7 @@
 | 
				
			||||||
# coding=utf8
 | 
					# coding=utf8
 | 
				
			||||||
import json
 | 
					import json
 | 
				
			||||||
 | 
					import io
 | 
				
			||||||
 | 
					import itertools
 | 
				
			||||||
 | 
					
 | 
				
			||||||
contractions = {}
 | 
					contractions = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -262,14 +264,30 @@ def get_token_properties(token, capitalize=False, remove_contractions=False):
 | 
				
			||||||
    props["F"] = token
 | 
					    props["F"] = token
 | 
				
			||||||
    return props
 | 
					    return props
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def create_entry(token, endings, capitalize=False, remove_contractions=False):
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def create_entry(token, endings, capitalize=False, remove_contractions=False):
 | 
				
			||||||
    properties = []
 | 
					    properties = []
 | 
				
			||||||
    properties.append(get_token_properties(token, capitalize=capitalize, remove_contractions=remove_contractions))
 | 
					    properties.append(get_token_properties(token, capitalize=capitalize, remove_contractions=remove_contractions))
 | 
				
			||||||
    for e in endings:
 | 
					    for e in endings:
 | 
				
			||||||
        properties.append(get_token_properties(e, remove_contractions=remove_contractions))
 | 
					        properties.append(get_token_properties(e, remove_contractions=remove_contractions))
 | 
				
			||||||
    return properties
 | 
					    return properties
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FIELDNAMES = ['F','L','pos']
 | 
				
			||||||
 | 
					def read_hardcoded(stream):
 | 
				
			||||||
 | 
					    hc_specials = {}
 | 
				
			||||||
 | 
					    for line in stream:
 | 
				
			||||||
 | 
					        line = line.strip()
 | 
				
			||||||
 | 
					        if line.startswith('#') or not line:
 | 
				
			||||||
 | 
					            continue
 | 
				
			||||||
 | 
					        key,_,rest = line.partition('\t')
 | 
				
			||||||
 | 
					        values = []
 | 
				
			||||||
 | 
					        for annotation in zip(*[ e.split('|') for e in rest.split('\t') ]):
 | 
				
			||||||
 | 
					            values.append({ k:v for k,v in itertools.izip_longest(FIELDNAMES,annotation) if v })
 | 
				
			||||||
 | 
					        hc_specials[key] = values
 | 
				
			||||||
 | 
					    return hc_specials
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def generate_specials():
 | 
					def generate_specials():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    specials = {}
 | 
					    specials = {}
 | 
				
			||||||
| 
						 | 
					@ -303,7 +321,10 @@ def generate_specials():
 | 
				
			||||||
                specials[special] = create_entry(token, endings, capitalize=True, remove_contractions=True)
 | 
					                specials[special] = create_entry(token, endings, capitalize=True, remove_contractions=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # add in hardcoded specials
 | 
					    # add in hardcoded specials
 | 
				
			||||||
    specials = dict(specials, **hardcoded_specials)
 | 
					    # changed it so it generates them from a file
 | 
				
			||||||
 | 
					    with io.open('abbrev.de.tab','r',encoding='utf8') as abbrev_:
 | 
				
			||||||
 | 
					        hc_specials = read_hardcoded(abbrev_)
 | 
				
			||||||
 | 
					    specials = dict(specials, **hc_specials)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return specials
 | 
					    return specials
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,6 @@
 | 
				
			||||||
\.\.\.
 | 
					\.\.\.
 | 
				
			||||||
(?<=[a-z])\.(?=[A-Z])
 | 
					(?<=[a-z])\.(?=[A-Z])
 | 
				
			||||||
(?<=[a-zA-Z])-(?=[a-zA-z])
 | 
					(?<=[a-zöäüßA-ZÖÄÜ"]):(?=[a-zöäüßA-ZÖÄÜ])
 | 
				
			||||||
 | 
					(?<=[a-zöäüßA-ZÖÄÜ"])>(?=[a-zöäüßA-ZÖÄÜ])
 | 
				
			||||||
 | 
					(?<=[a-zöäüßA-ZÖÄÜ"])<(?=[a-zöäüßA-ZÖÄÜ])
 | 
				
			||||||
 | 
					(?<=[a-zöäüßA-ZÖÄÜ"])=(?=[a-zöäüßA-ZÖÄÜ])
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,7 @@
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
*
 | 
					*
 | 
				
			||||||
<
 | 
					<
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
$
 | 
					$
 | 
				
			||||||
£
 | 
					£
 | 
				
			||||||
„
 | 
					„
 | 
				
			||||||
| 
						 | 
					@ -20,3 +21,7 @@ a-
 | 
				
			||||||
‘
 | 
					‘
 | 
				
			||||||
....
 | 
					....
 | 
				
			||||||
...
 | 
					...
 | 
				
			||||||
 | 
					‚
 | 
				
			||||||
 | 
					»
 | 
				
			||||||
 | 
					_
 | 
				
			||||||
 | 
					§
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,27 +1,4 @@
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    "\t": [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "F": "\t",
 | 
					 | 
				
			||||||
            "pos": "SP"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "\n": [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "F": "\n",
 | 
					 | 
				
			||||||
            "pos": "SP"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    " ": [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "F": " ",
 | 
					 | 
				
			||||||
            "pos": "SP"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "\")": [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "F": "\")"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "''": [
 | 
					    "''": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "''"
 | 
					            "F": "''"
 | 
				
			||||||
| 
						 | 
					@ -217,6 +194,11 @@
 | 
				
			||||||
            "F": "<333"
 | 
					            "F": "<333"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "<space>": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "SP"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "=)": [
 | 
					    "=)": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "=)"
 | 
					            "F": "=)"
 | 
				
			||||||
| 
						 | 
					@ -267,6 +249,16 @@
 | 
				
			||||||
            "F": "Abk."
 | 
					            "F": "Abk."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "Abs.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "Abs."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "Abt.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "Abt."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "Apr.": [
 | 
					    "Apr.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "Apr."
 | 
					            "F": "Apr."
 | 
				
			||||||
| 
						 | 
					@ -277,6 +269,26 @@
 | 
				
			||||||
            "F": "Aug."
 | 
					            "F": "Aug."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "B.A.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "B.A."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "B.Sc.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "B.Sc."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "Bd.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "Bd."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "Betr.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "Betr."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "Bf.": [
 | 
					    "Bf.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "Bf."
 | 
					            "F": "Bf."
 | 
				
			||||||
| 
						 | 
					@ -292,6 +304,11 @@
 | 
				
			||||||
            "F": "Biol."
 | 
					            "F": "Biol."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "Bsp.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "Bsp."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "Chr.": [
 | 
					    "Chr.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "Chr."
 | 
					            "F": "Chr."
 | 
				
			||||||
| 
						 | 
					@ -342,6 +359,16 @@
 | 
				
			||||||
            "F": "Dr."
 | 
					            "F": "Dr."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "Fa.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "Fa."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "Fam.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "Fam."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "Feb.": [
 | 
					    "Feb.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "Feb."
 | 
					            "F": "Feb."
 | 
				
			||||||
| 
						 | 
					@ -387,6 +414,16 @@
 | 
				
			||||||
            "F": "Hrgs."
 | 
					            "F": "Hrgs."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "Hrn.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "Hrn."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "Hrsg.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "Hrsg."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "Ing.": [
 | 
					    "Ing.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "Ing."
 | 
					            "F": "Ing."
 | 
				
			||||||
| 
						 | 
					@ -397,11 +434,21 @@
 | 
				
			||||||
            "F": "Jan."
 | 
					            "F": "Jan."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "Jh.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "Jh."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "Jhd.": [
 | 
					    "Jhd.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "Jhd."
 | 
					            "F": "Jhd."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "Jr.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "Jr."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "Jul.": [
 | 
					    "Jul.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "Jul."
 | 
					            "F": "Jul."
 | 
				
			||||||
| 
						 | 
					@ -412,21 +459,61 @@
 | 
				
			||||||
            "F": "Jun."
 | 
					            "F": "Jun."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "K.O.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "K.O."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "L.A.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "L.A."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "M.A.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "M.A."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "M.Sc.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "M.Sc."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "Mi.": [
 | 
					    "Mi.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "Mi."
 | 
					            "F": "Mi."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "Mio.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "Mio."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "Mo.": [
 | 
					    "Mo.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "Mo."
 | 
					            "F": "Mo."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "Mr.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "Mr."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "Mrd.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "Mrd."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "Mrz.": [
 | 
					    "Mrz.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "Mrz."
 | 
					            "F": "Mrz."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "MwSt.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "MwSt."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "M\u00e4r.": [
 | 
					    "M\u00e4r.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "M\u00e4r."
 | 
					            "F": "M\u00e4r."
 | 
				
			||||||
| 
						 | 
					@ -452,16 +539,31 @@
 | 
				
			||||||
            "F": "Nr."
 | 
					            "F": "Nr."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "O.K.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "O.K."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "Okt.": [
 | 
					    "Okt.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "Okt."
 | 
					            "F": "Okt."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "Orig.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "Orig."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "P.S.": [
 | 
					    "P.S.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "P.S."
 | 
					            "F": "P.S."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "Pkt.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "Pkt."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "Prof.": [
 | 
					    "Prof.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "Prof."
 | 
					            "F": "Prof."
 | 
				
			||||||
| 
						 | 
					@ -472,6 +574,11 @@
 | 
				
			||||||
            "F": "R.I.P."
 | 
					            "F": "R.I.P."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "Red.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "Red."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "S'": [
 | 
					    "S'": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "S'",
 | 
					            "F": "S'",
 | 
				
			||||||
| 
						 | 
					@ -503,6 +610,41 @@
 | 
				
			||||||
            "F": "St."
 | 
					            "F": "St."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "Std.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "Std."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "Str.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "Str."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "Tel.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "Tel."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "Tsd.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "Tsd."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "U.S.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "U.S."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "U.S.A.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "U.S.A."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "U.S.S.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "U.S.S."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "Univ.": [
 | 
					    "Univ.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "Univ."
 | 
					            "F": "Univ."
 | 
				
			||||||
| 
						 | 
					@ -513,6 +655,30 @@
 | 
				
			||||||
            "F": "V_V"
 | 
					            "F": "V_V"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "Vol.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "Vol."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "\\\")": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "\\\")"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "\\n": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "\\n",
 | 
				
			||||||
 | 
					            "L": "<nl>",
 | 
				
			||||||
 | 
					            "pos": "SP"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "\\t": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "\\t",
 | 
				
			||||||
 | 
					            "L": "<tab>",
 | 
				
			||||||
 | 
					            "pos": "SP"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "^_^": [
 | 
					    "^_^": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "^_^"
 | 
					            "F": "^_^"
 | 
				
			||||||
| 
						 | 
					@ -528,6 +694,11 @@
 | 
				
			||||||
            "F": "a.D."
 | 
					            "F": "a.D."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "a.M.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "a.M."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "a.Z.": [
 | 
					    "a.Z.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "a.Z."
 | 
					            "F": "a.Z."
 | 
				
			||||||
| 
						 | 
					@ -548,9 +719,15 @@
 | 
				
			||||||
            "F": "al."
 | 
					            "F": "al."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "allg.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "allg."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "auf'm": [
 | 
					    "auf'm": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "auf"
 | 
					            "F": "auf",
 | 
				
			||||||
 | 
					            "L": "auf"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "'m",
 | 
					            "F": "'m",
 | 
				
			||||||
| 
						 | 
					@ -572,11 +749,31 @@
 | 
				
			||||||
            "F": "biol."
 | 
					            "F": "biol."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "bspw.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "bspw."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "bzgl.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "bzgl."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "bzw.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "bzw."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "c.": [
 | 
					    "c.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "c."
 | 
					            "F": "c."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "ca.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "ca."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "co.": [
 | 
					    "co.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "co."
 | 
					            "F": "co."
 | 
				
			||||||
| 
						 | 
					@ -587,9 +784,20 @@
 | 
				
			||||||
            "F": "d."
 | 
					            "F": "d."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "d.h.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "d.h."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "dgl.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "dgl."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "du's": [
 | 
					    "du's": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "du"
 | 
					            "F": "du",
 | 
				
			||||||
 | 
					            "L": "du"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "'s",
 | 
					            "F": "'s",
 | 
				
			||||||
| 
						 | 
					@ -611,19 +819,35 @@
 | 
				
			||||||
            "F": "e.g."
 | 
					            "F": "e.g."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "ebd.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "ebd."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "ehem.": [
 | 
					    "ehem.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "ehem."
 | 
					            "F": "ehem."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "eigtl.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "eigtl."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "engl.": [
 | 
					    "engl.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "engl."
 | 
					            "F": "engl."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "entspr.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "entspr."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "er's": [
 | 
					    "er's": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "er"
 | 
					            "F": "er",
 | 
				
			||||||
 | 
					            "L": "er"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "'s",
 | 
					            "F": "'s",
 | 
				
			||||||
| 
						 | 
					@ -640,11 +864,26 @@
 | 
				
			||||||
            "F": "etc."
 | 
					            "F": "etc."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "ev.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "ev."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "evtl.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "evtl."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "f.": [
 | 
					    "f.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "f."
 | 
					            "F": "f."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "frz.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "frz."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "g.": [
 | 
					    "g.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "g."
 | 
					            "F": "g."
 | 
				
			||||||
| 
						 | 
					@ -660,6 +899,11 @@
 | 
				
			||||||
            "F": "gegr."
 | 
					            "F": "gegr."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "gem.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "gem."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "ggf.": [
 | 
					    "ggf.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "ggf."
 | 
					            "F": "ggf."
 | 
				
			||||||
| 
						 | 
					@ -687,23 +931,39 @@
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    "hinter'm": [
 | 
					    "hinter'm": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "hinter"
 | 
					            "F": "hinter",
 | 
				
			||||||
 | 
					            "L": "hinter"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "'m",
 | 
					            "F": "'m",
 | 
				
			||||||
            "L": "dem"
 | 
					            "L": "dem"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "hrsg.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "hrsg."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "i.": [
 | 
					    "i.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "i."
 | 
					            "F": "i."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "i.A.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "i.A."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "i.G.": [
 | 
					    "i.G.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "i.G."
 | 
					            "F": "i.G."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "i.O.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "i.O."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "i.Tr.": [
 | 
					    "i.Tr.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "i.Tr."
 | 
					            "F": "i.Tr."
 | 
				
			||||||
| 
						 | 
					@ -714,6 +974,11 @@
 | 
				
			||||||
            "F": "i.V."
 | 
					            "F": "i.V."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "i.d.R.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "i.d.R."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "i.e.": [
 | 
					    "i.e.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "i.e."
 | 
					            "F": "i.e."
 | 
				
			||||||
| 
						 | 
					@ -721,7 +986,8 @@
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    "ich's": [
 | 
					    "ich's": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "ich"
 | 
					            "F": "ich",
 | 
				
			||||||
 | 
					            "L": "ich"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "'s",
 | 
					            "F": "'s",
 | 
				
			||||||
| 
						 | 
					@ -730,7 +996,8 @@
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    "ihr's": [
 | 
					    "ihr's": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "ihr"
 | 
					            "F": "ihr",
 | 
				
			||||||
 | 
					            "L": "ihr"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "'s",
 | 
					            "F": "'s",
 | 
				
			||||||
| 
						 | 
					@ -757,6 +1024,11 @@
 | 
				
			||||||
            "F": "j."
 | 
					            "F": "j."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "jr.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "jr."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "jun.": [
 | 
					    "jun.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "jun."
 | 
					            "F": "jun."
 | 
				
			||||||
| 
						 | 
					@ -772,11 +1044,21 @@
 | 
				
			||||||
            "F": "k."
 | 
					            "F": "k."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "kath.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "kath."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "l.": [
 | 
					    "l.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "l."
 | 
					            "F": "l."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "lat.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "lat."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "lt.": [
 | 
					    "lt.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "lt."
 | 
					            "F": "lt."
 | 
				
			||||||
| 
						 | 
					@ -787,11 +1069,46 @@
 | 
				
			||||||
            "F": "m."
 | 
					            "F": "m."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "m.E.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "m.E."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "m.M.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "m.M."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "max.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "max."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "min.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "min."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "mind.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "mind."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "mtl.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "mtl."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "n.": [
 | 
					    "n.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "n."
 | 
					            "F": "n."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "n.Chr.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "n.Chr."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "nat.": [
 | 
					    "nat.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "nat."
 | 
					            "F": "nat."
 | 
				
			||||||
| 
						 | 
					@ -807,6 +1124,31 @@
 | 
				
			||||||
            "F": "o.O"
 | 
					            "F": "o.O"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "o.a.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "o.a."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "o.g.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "o.g."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "o.k.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "o.k."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "o.\u00c4.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "o.\u00c4."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "o.\u00e4.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "o.\u00e4."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "o_O": [
 | 
					    "o_O": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "o_O"
 | 
					            "F": "o_O"
 | 
				
			||||||
| 
						 | 
					@ -817,6 +1159,11 @@
 | 
				
			||||||
            "F": "o_o"
 | 
					            "F": "o_o"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "orig.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "orig."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "p.": [
 | 
					    "p.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "p."
 | 
					            "F": "p."
 | 
				
			||||||
| 
						 | 
					@ -827,6 +1174,21 @@
 | 
				
			||||||
            "F": "p.a."
 | 
					            "F": "p.a."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "p.s.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "p.s."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "pers.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "pers."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "phil.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "phil."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "q.": [
 | 
					    "q.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "q."
 | 
					            "F": "q."
 | 
				
			||||||
| 
						 | 
					@ -847,6 +1209,11 @@
 | 
				
			||||||
            "F": "rer."
 | 
					            "F": "rer."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "r\u00f6m.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "r\u00f6m."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "s'": [
 | 
					    "s'": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "s'",
 | 
					            "F": "s'",
 | 
				
			||||||
| 
						 | 
					@ -858,6 +1225,11 @@
 | 
				
			||||||
            "F": "s."
 | 
					            "F": "s."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "s.o.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "s.o."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "sen.": [
 | 
					    "sen.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "sen."
 | 
					            "F": "sen."
 | 
				
			||||||
| 
						 | 
					@ -865,23 +1237,49 @@
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    "sie's": [
 | 
					    "sie's": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "sie"
 | 
					            "F": "sie",
 | 
				
			||||||
 | 
					            "L": "sie"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "'s",
 | 
					            "F": "'s",
 | 
				
			||||||
            "L": "es"
 | 
					            "L": "es"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "sog.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "sog."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "std.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "std."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "stellv.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "stellv."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "t.": [
 | 
					    "t.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "t."
 | 
					            "F": "t."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "t\u00e4gl.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "t\u00e4gl."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "u.": [
 | 
					    "u.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "u."
 | 
					            "F": "u."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "u.U.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "u.U."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "u.a.": [
 | 
					    "u.a.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "u.a."
 | 
					            "F": "u.a."
 | 
				
			||||||
| 
						 | 
					@ -892,28 +1290,75 @@
 | 
				
			||||||
            "F": "u.s.w."
 | 
					            "F": "u.s.w."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "u.v.m.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "u.v.m."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "unter'm": [
 | 
					    "unter'm": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "unter"
 | 
					            "F": "unter",
 | 
				
			||||||
 | 
					            "L": "unter"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "'m",
 | 
					            "F": "'m",
 | 
				
			||||||
            "L": "dem"
 | 
					            "L": "dem"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "usf.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "usf."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "usw.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "usw."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "uvm.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "uvm."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "v.": [
 | 
					    "v.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "v."
 | 
					            "F": "v."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "v.Chr.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "v.Chr."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "v.a.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "v.a."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "v.l.n.r.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "v.l.n.r."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "vgl.": [
 | 
					    "vgl.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "vgl."
 | 
					            "F": "vgl."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "vllt.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "vllt."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "vlt.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "vlt."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "vor'm": [
 | 
					    "vor'm": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "vor"
 | 
					            "F": "vor",
 | 
				
			||||||
 | 
					            "L": "vor"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "'m",
 | 
					            "F": "'m",
 | 
				
			||||||
| 
						 | 
					@ -932,13 +1377,19 @@
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    "wir's": [
 | 
					    "wir's": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "wir"
 | 
					            "F": "wir",
 | 
				
			||||||
 | 
					            "L": "wir"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "'s",
 | 
					            "F": "'s",
 | 
				
			||||||
            "L": "es"
 | 
					            "L": "es"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "wiss.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "wiss."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "x.": [
 | 
					    "x.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "x."
 | 
					            "F": "x."
 | 
				
			||||||
| 
						 | 
					@ -969,19 +1420,60 @@
 | 
				
			||||||
            "F": "z.B."
 | 
					            "F": "z.B."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "z.Bsp.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "z.Bsp."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "z.T.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "z.T."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "z.Z.": [
 | 
					    "z.Z.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "z.Z."
 | 
					            "F": "z.Z."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "z.Zt.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "z.Zt."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "z.b.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "z.b."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "zzgl.": [
 | 
					    "zzgl.": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "zzgl."
 | 
					            "F": "zzgl."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "\u00e4.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "\u00e4."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "\u00f6.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "\u00f6."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "\u00f6sterr.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "\u00f6sterr."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "\u00fc.": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "F": "\u00fc."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "\u00fcber'm": [
 | 
					    "\u00fcber'm": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "\u00fcber"
 | 
					            "F": "\u00fcber",
 | 
				
			||||||
 | 
					            "L": "\u00fcber"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "F": "'m",
 | 
					            "F": "'m",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,14 +13,61 @@
 | 
				
			||||||
;
 | 
					;
 | 
				
			||||||
'
 | 
					'
 | 
				
			||||||
”
 | 
					”
 | 
				
			||||||
 | 
					“
 | 
				
			||||||
 | 
					«
 | 
				
			||||||
 | 
					_
 | 
				
			||||||
''
 | 
					''
 | 
				
			||||||
's
 | 
					's
 | 
				
			||||||
'S
 | 
					'S
 | 
				
			||||||
’s
 | 
					’s
 | 
				
			||||||
’S
 | 
					’S
 | 
				
			||||||
’
 | 
					’
 | 
				
			||||||
 | 
					‘
 | 
				
			||||||
 | 
					°
 | 
				
			||||||
 | 
					€
 | 
				
			||||||
\.\.
 | 
					\.\.
 | 
				
			||||||
\.\.\.
 | 
					\.\.\.
 | 
				
			||||||
\.\.\.\.
 | 
					\.\.\.\.
 | 
				
			||||||
(?<=[a-z0-9)\]"'%\)])\.
 | 
					(?<=[a-zäöüßÖÄÜ)\]"'´«‘’%\)²“”])\.
 | 
				
			||||||
 | 
					\-\-
 | 
				
			||||||
 | 
					´
 | 
				
			||||||
 | 
					(?<=[0-9])km²
 | 
				
			||||||
 | 
					(?<=[0-9])m²
 | 
				
			||||||
 | 
					(?<=[0-9])cm²
 | 
				
			||||||
 | 
					(?<=[0-9])mm²
 | 
				
			||||||
 | 
					(?<=[0-9])km³
 | 
				
			||||||
 | 
					(?<=[0-9])m³
 | 
				
			||||||
 | 
					(?<=[0-9])cm³
 | 
				
			||||||
 | 
					(?<=[0-9])mm³
 | 
				
			||||||
 | 
					(?<=[0-9])ha
 | 
				
			||||||
(?<=[0-9])km
 | 
					(?<=[0-9])km
 | 
				
			||||||
 | 
					(?<=[0-9])m
 | 
				
			||||||
 | 
					(?<=[0-9])cm
 | 
				
			||||||
 | 
					(?<=[0-9])mm
 | 
				
			||||||
 | 
					(?<=[0-9])µm
 | 
				
			||||||
 | 
					(?<=[0-9])nm
 | 
				
			||||||
 | 
					(?<=[0-9])yd
 | 
				
			||||||
 | 
					(?<=[0-9])in
 | 
				
			||||||
 | 
					(?<=[0-9])ft
 | 
				
			||||||
 | 
					(?<=[0-9])kg
 | 
				
			||||||
 | 
					(?<=[0-9])g
 | 
				
			||||||
 | 
					(?<=[0-9])mg
 | 
				
			||||||
 | 
					(?<=[0-9])µg
 | 
				
			||||||
 | 
					(?<=[0-9])t
 | 
				
			||||||
 | 
					(?<=[0-9])lb
 | 
				
			||||||
 | 
					(?<=[0-9])oz
 | 
				
			||||||
 | 
					(?<=[0-9])m/s
 | 
				
			||||||
 | 
					(?<=[0-9])km/h
 | 
				
			||||||
 | 
					(?<=[0-9])mph
 | 
				
			||||||
 | 
					(?<=[0-9])°C
 | 
				
			||||||
 | 
					(?<=[0-9])°K
 | 
				
			||||||
 | 
					(?<=[0-9])°F
 | 
				
			||||||
 | 
					(?<=[0-9])hPa
 | 
				
			||||||
 | 
					(?<=[0-9])Pa
 | 
				
			||||||
 | 
					(?<=[0-9])mbar
 | 
				
			||||||
 | 
					(?<=[0-9])mb
 | 
				
			||||||
 | 
					(?<=[0-9])T
 | 
				
			||||||
 | 
					(?<=[0-9])G
 | 
				
			||||||
 | 
					(?<=[0-9])M
 | 
				
			||||||
 | 
					(?<=[0-9])K
 | 
				
			||||||
 | 
					(?<=[0-9])kb
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1
									
								
								setup.py
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								setup.py
									
									
									
									
									
								
							| 
						 | 
					@ -47,6 +47,7 @@ MOD_NAMES = [
 | 
				
			||||||
    'spacy.syntax._state',
 | 
					    'spacy.syntax._state',
 | 
				
			||||||
    'spacy.tokenizer',
 | 
					    'spacy.tokenizer',
 | 
				
			||||||
    'spacy.syntax.parser',
 | 
					    'spacy.syntax.parser',
 | 
				
			||||||
 | 
					    'spacy.syntax.nonproj',
 | 
				
			||||||
    'spacy.syntax.transition_system',
 | 
					    'spacy.syntax.transition_system',
 | 
				
			||||||
    'spacy.syntax.arc_eager',
 | 
					    'spacy.syntax.arc_eager',
 | 
				
			||||||
    'spacy.syntax._parse_features',
 | 
					    'spacy.syntax._parse_features',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,4 +6,4 @@ from ..language import Language
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class German(Language):
 | 
					class German(Language):
 | 
				
			||||||
    pass
 | 
					    lang = 'de'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,8 @@ try:
 | 
				
			||||||
except ImportError:
 | 
					except ImportError:
 | 
				
			||||||
    import json
 | 
					    import json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from .syntax import nonproj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def tags_to_entities(tags):
 | 
					def tags_to_entities(tags):
 | 
				
			||||||
    entities = []
 | 
					    entities = []
 | 
				
			||||||
| 
						 | 
					@ -237,33 +239,13 @@ cdef class GoldParse:
 | 
				
			||||||
                self.labels[i] = annot_tuples[4][gold_i]
 | 
					                self.labels[i] = annot_tuples[4][gold_i]
 | 
				
			||||||
                self.ner[i] = annot_tuples[5][gold_i]
 | 
					                self.ner[i] = annot_tuples[5][gold_i]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # If we have any non-projective arcs, i.e. crossing brackets, consider
 | 
					        cycle = nonproj.contains_cycle(self.heads)
 | 
				
			||||||
        # the heads for those words missing in the gold-standard.
 | 
					        if cycle != None:
 | 
				
			||||||
        # This way, we can train from these sentences
 | 
					            raise Exception("Cycle found: %s" % cycle)
 | 
				
			||||||
        cdef int w1, w2, h1, h2
 | 
					 | 
				
			||||||
        if make_projective:
 | 
					 | 
				
			||||||
            heads = list(self.heads)
 | 
					 | 
				
			||||||
            for w1 in range(self.length):
 | 
					 | 
				
			||||||
                if heads[w1] is not None:
 | 
					 | 
				
			||||||
                    h1 = heads[w1]
 | 
					 | 
				
			||||||
                    for w2 in range(w1+1, self.length):
 | 
					 | 
				
			||||||
                        if heads[w2] is not None:
 | 
					 | 
				
			||||||
                            h2 = heads[w2]
 | 
					 | 
				
			||||||
                            if _arcs_cross(w1, h1, w2, h2):
 | 
					 | 
				
			||||||
                                self.heads[w1] = None
 | 
					 | 
				
			||||||
                                self.labels[w1] = ''
 | 
					 | 
				
			||||||
                                self.heads[w2] = None
 | 
					 | 
				
			||||||
                                self.labels[w2] = ''
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Check there are no cycles in the dependencies, i.e. we are a tree
 | 
					        if make_projective:
 | 
				
			||||||
        for w in range(self.length):
 | 
					            proj_heads,_ = nonproj.PseudoProjectivity.projectivize(self.heads,self.labels)
 | 
				
			||||||
            seen = set([w])
 | 
					            self.heads = proj_heads
 | 
				
			||||||
            head = w
 | 
					 | 
				
			||||||
            while self.heads[head] != head and self.heads[head] != None:
 | 
					 | 
				
			||||||
                head = self.heads[head]
 | 
					 | 
				
			||||||
                if head in seen:
 | 
					 | 
				
			||||||
                    raise Exception("Cycle found: %s" % seen)
 | 
					 | 
				
			||||||
                seen.add(head)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.brackets = {}
 | 
					        self.brackets = {}
 | 
				
			||||||
        for (gold_start, gold_end, label_str) in brackets:
 | 
					        for (gold_start, gold_end, label_str) in brackets:
 | 
				
			||||||
| 
						 | 
					@ -278,25 +260,18 @@ cdef class GoldParse:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def is_projective(self):
 | 
					    def is_projective(self):
 | 
				
			||||||
        heads = list(self.heads)
 | 
					        return not nonproj.is_nonproj_tree(self.heads)
 | 
				
			||||||
        for w1 in range(self.length):
 | 
					 | 
				
			||||||
            if heads[w1] is not None:
 | 
					 | 
				
			||||||
                h1 = heads[w1]
 | 
					 | 
				
			||||||
                for w2 in range(self.length):
 | 
					 | 
				
			||||||
                    if heads[w2] is not None and _arcs_cross(w1, h1, w2, heads[w2]):
 | 
					 | 
				
			||||||
                        return False
 | 
					 | 
				
			||||||
        return True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
cdef int _arcs_cross(int w1, int h1, int w2, int h2) except -1:
 | 
					 | 
				
			||||||
    if w1 > h1:
 | 
					 | 
				
			||||||
        w1, h1 = h1, w1
 | 
					 | 
				
			||||||
    if w2 > h2:
 | 
					 | 
				
			||||||
        w2, h2 = h2, w2
 | 
					 | 
				
			||||||
    if w1 > w2:
 | 
					 | 
				
			||||||
        w1, h1, w2, h2 = w2, h2, w1, h1
 | 
					 | 
				
			||||||
    return w1 < w2 < h1 < h2 or w1 < w2 == h2 < h1
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def is_punct_label(label):
 | 
					def is_punct_label(label):
 | 
				
			||||||
    return label == 'P' or label.lower() == 'punct'
 | 
					    return label == 'P' or label.lower() == 'punct'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										0
									
								
								spacy/syntax/nonproj.pxd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								spacy/syntax/nonproj.pxd
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										200
									
								
								spacy/syntax/nonproj.pyx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								spacy/syntax/nonproj.pyx
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,200 @@
 | 
				
			||||||
 | 
					from copy import copy
 | 
				
			||||||
 | 
					from collections import Counter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..tokens.doc cimport Doc
 | 
				
			||||||
 | 
					from spacy.attrs import DEP, HEAD
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def ancestors(tokenid, heads):
 | 
				
			||||||
 | 
					    # returns all words going from the word up the path to the root
 | 
				
			||||||
 | 
					    # the path to root cannot be longer than the number of words in the sentence
 | 
				
			||||||
 | 
					    # this function ends after at most len(heads) steps 
 | 
				
			||||||
 | 
					    # because it would otherwise loop indefinitely on cycles
 | 
				
			||||||
 | 
					    head = tokenid
 | 
				
			||||||
 | 
					    cnt = 0
 | 
				
			||||||
 | 
					    while heads[head] != head and cnt < len(heads):
 | 
				
			||||||
 | 
					        head = heads[head]
 | 
				
			||||||
 | 
					        cnt += 1
 | 
				
			||||||
 | 
					        yield head
 | 
				
			||||||
 | 
					        if head == None:
 | 
				
			||||||
 | 
					            break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def contains_cycle(heads):
 | 
				
			||||||
 | 
					    # in an acyclic tree, the path from each word following
 | 
				
			||||||
 | 
					    # the head relation upwards always ends at the root node
 | 
				
			||||||
 | 
					    for tokenid in range(len(heads)):
 | 
				
			||||||
 | 
					        seen = set([tokenid])
 | 
				
			||||||
 | 
					        for ancestor in ancestors(tokenid,heads):
 | 
				
			||||||
 | 
					            if ancestor in seen:
 | 
				
			||||||
 | 
					                return seen
 | 
				
			||||||
 | 
					            seen.add(ancestor)
 | 
				
			||||||
 | 
					    return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def is_nonproj_arc(tokenid, heads):
 | 
				
			||||||
 | 
					    # definition (e.g. Havelka 2007): an arc h -> d, h < d is non-projective
 | 
				
			||||||
 | 
					    # if there is a token k, h < k < d such that h is not
 | 
				
			||||||
 | 
					    # an ancestor of k. Same for h -> d, h > d
 | 
				
			||||||
 | 
					    head = heads[tokenid]
 | 
				
			||||||
 | 
					    if head == tokenid: # root arcs cannot be non-projective
 | 
				
			||||||
 | 
					        return False
 | 
				
			||||||
 | 
					    elif head == None: # unattached tokens cannot be non-projective
 | 
				
			||||||
 | 
					        return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    start, end = (head+1, tokenid) if head < tokenid else (tokenid+1, head)
 | 
				
			||||||
 | 
					    for k in range(start,end):
 | 
				
			||||||
 | 
					        for ancestor in ancestors(k,heads):
 | 
				
			||||||
 | 
					            if ancestor == None: # for unattached tokens/subtrees
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
 | 
					            elif ancestor == head: # normal case: k dominated by h
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
 | 
					        else: # head not in ancestors: d -> h is non-projective
 | 
				
			||||||
 | 
					            return True
 | 
				
			||||||
 | 
					    return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def is_nonproj_tree(heads):
 | 
				
			||||||
 | 
					    # a tree is non-projective if at least one arc is non-projective
 | 
				
			||||||
 | 
					    return any( is_nonproj_arc(word,heads) for word in range(len(heads)) )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cdef class PseudoProjectivity:
 | 
				
			||||||
 | 
					    # implements the projectivize/deprojectivize mechanism in Nivre & Nilsson 2005
 | 
				
			||||||
 | 
					    # for doing pseudo-projective parsing
 | 
				
			||||||
 | 
					    # implementation uses the HEAD decoration scheme
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    delimiter = '||'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def decompose(cls, label):
 | 
				
			||||||
 | 
					        return label.partition(cls.delimiter)[::2]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def is_decorated(cls, label):
 | 
				
			||||||
 | 
					        return label.find(cls.delimiter) != -1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def preprocess_training_data(cls, gold_tuples, label_freq_cutoff=30):
 | 
				
			||||||
 | 
					        preprocessed = []
 | 
				
			||||||
 | 
					        freqs = Counter()
 | 
				
			||||||
 | 
					        for raw_text, sents in gold_tuples:
 | 
				
			||||||
 | 
					            prepro_sents = []
 | 
				
			||||||
 | 
					            for (ids, words, tags, heads, labels, iob), ctnts in sents:
 | 
				
			||||||
 | 
					                proj_heads,deco_labels = cls.projectivize(heads,labels)
 | 
				
			||||||
 | 
					                # set the label to ROOT for each root dependent
 | 
				
			||||||
 | 
					                deco_labels = [ 'ROOT' if head == i else deco_labels[i] for i,head in enumerate(proj_heads) ]
 | 
				
			||||||
 | 
					                # count label frequencies
 | 
				
			||||||
 | 
					                if label_freq_cutoff > 0:
 | 
				
			||||||
 | 
					                    freqs.update( label for label in deco_labels if cls.is_decorated(label) )
 | 
				
			||||||
 | 
					                prepro_sents.append(((ids,words,tags,proj_heads,deco_labels,iob), ctnts))
 | 
				
			||||||
 | 
					            preprocessed.append((raw_text, prepro_sents))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if label_freq_cutoff > 0:
 | 
				
			||||||
 | 
					            return cls._filter_labels(preprocessed,label_freq_cutoff,freqs)
 | 
				
			||||||
 | 
					        return preprocessed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def projectivize(cls, heads, labels):
 | 
				
			||||||
 | 
					        # use the algorithm by Nivre & Nilsson 2005
 | 
				
			||||||
 | 
					        # assumes heads to be a proper tree, i.e. connected and cycle-free
 | 
				
			||||||
 | 
					        # returns a new pair (heads,labels) which encode
 | 
				
			||||||
 | 
					        # a projective and decorated tree
 | 
				
			||||||
 | 
					        proj_heads = copy(heads)
 | 
				
			||||||
 | 
					        smallest_np_arc = cls._get_smallest_nonproj_arc(proj_heads)
 | 
				
			||||||
 | 
					        if smallest_np_arc == None: # this sentence is already projective
 | 
				
			||||||
 | 
					            return proj_heads, copy(labels)
 | 
				
			||||||
 | 
					        while smallest_np_arc != None:
 | 
				
			||||||
 | 
					            cls._lift(smallest_np_arc, proj_heads)
 | 
				
			||||||
 | 
					            smallest_np_arc = cls._get_smallest_nonproj_arc(proj_heads)
 | 
				
			||||||
 | 
					        deco_labels = cls._decorate(heads, proj_heads, labels)
 | 
				
			||||||
 | 
					        return proj_heads, deco_labels
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def deprojectivize(cls, Doc tokens):
 | 
				
			||||||
 | 
					        # reattach arcs with decorated labels (following HEAD scheme)
 | 
				
			||||||
 | 
					        # for each decorated arc X||Y, search top-down, left-to-right,
 | 
				
			||||||
 | 
					        # breadth-first until hitting a Y then make this the new head
 | 
				
			||||||
 | 
					        parse = tokens.to_array([HEAD, DEP])
 | 
				
			||||||
 | 
					        labels = [ tokens.vocab.strings[int(p[1])] for p in parse ]
 | 
				
			||||||
 | 
					        for token in tokens:
 | 
				
			||||||
 | 
					            if cls.is_decorated(token.dep_):
 | 
				
			||||||
 | 
					                newlabel,headlabel = cls.decompose(token.dep_)
 | 
				
			||||||
 | 
					                newhead = cls._find_new_head(token,headlabel)
 | 
				
			||||||
 | 
					                parse[token.i,1] = tokens.vocab.strings[newlabel]
 | 
				
			||||||
 | 
					                parse[token.i,0] = newhead.i - token.i
 | 
				
			||||||
 | 
					        tokens.from_array([HEAD, DEP],parse)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def _decorate(cls, heads, proj_heads, labels):
 | 
				
			||||||
 | 
					        # uses decoration scheme HEAD from Nivre & Nilsson 2005
 | 
				
			||||||
 | 
					        assert(len(heads) == len(proj_heads) == len(labels))
 | 
				
			||||||
 | 
					        deco_labels = []
 | 
				
			||||||
 | 
					        for tokenid,head in enumerate(heads):
 | 
				
			||||||
 | 
					            if head != proj_heads[tokenid]:
 | 
				
			||||||
 | 
					                deco_labels.append('%s%s%s' % (labels[tokenid],cls.delimiter,labels[head]))
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                deco_labels.append(labels[tokenid])
 | 
				
			||||||
 | 
					        return deco_labels
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def _get_smallest_nonproj_arc(cls, heads):
 | 
				
			||||||
 | 
					        # return the smallest non-proj arc or None
 | 
				
			||||||
 | 
					        # where size is defined as the distance between dep and head
 | 
				
			||||||
 | 
					        # and ties are broken left to right
 | 
				
			||||||
 | 
					        smallest_size = float('inf')
 | 
				
			||||||
 | 
					        smallest_np_arc = None
 | 
				
			||||||
 | 
					        for tokenid,head in enumerate(heads):
 | 
				
			||||||
 | 
					            size = abs(tokenid-head)
 | 
				
			||||||
 | 
					            if size < smallest_size and is_nonproj_arc(tokenid,heads):
 | 
				
			||||||
 | 
					                smallest_size = size
 | 
				
			||||||
 | 
					                smallest_np_arc = tokenid
 | 
				
			||||||
 | 
					        return smallest_np_arc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def _lift(cls, tokenid, heads):
 | 
				
			||||||
 | 
					        # reattaches a word to it's grandfather
 | 
				
			||||||
 | 
					        head = heads[tokenid]
 | 
				
			||||||
 | 
					        ghead = heads[head]
 | 
				
			||||||
 | 
					        # attach to ghead if head isn't attached to root else attach to root
 | 
				
			||||||
 | 
					        heads[tokenid] = ghead if head != ghead else tokenid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def _find_new_head(cls, token, headlabel):
 | 
				
			||||||
 | 
					        # search through the tree starting from root
 | 
				
			||||||
 | 
					        # returns the id of the first descendant with the given label
 | 
				
			||||||
 | 
					        # if there is none, return the current head (no change)
 | 
				
			||||||
 | 
					        queue = [token.head]
 | 
				
			||||||
 | 
					        while queue:
 | 
				
			||||||
 | 
					            next_queue = []
 | 
				
			||||||
 | 
					            for qtoken in queue:
 | 
				
			||||||
 | 
					                for child in qtoken.children:
 | 
				
			||||||
 | 
					                    if child == token:
 | 
				
			||||||
 | 
					                        continue
 | 
				
			||||||
 | 
					                    if child.dep_ == headlabel:
 | 
				
			||||||
 | 
					                        return child
 | 
				
			||||||
 | 
					                    next_queue.append(child)
 | 
				
			||||||
 | 
					            queue = next_queue
 | 
				
			||||||
 | 
					        return token.head
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def _filter_labels(cls, gold_tuples, cutoff, freqs):
 | 
				
			||||||
 | 
					        # throw away infrequent decorated labels
 | 
				
			||||||
 | 
					        # can't learn them reliably anyway and keeps label set smaller
 | 
				
			||||||
 | 
					        filtered = []
 | 
				
			||||||
 | 
					        for raw_text, sents in gold_tuples:
 | 
				
			||||||
 | 
					            filtered_sents = []
 | 
				
			||||||
 | 
					            for (ids, words, tags, heads, labels, iob), ctnts in sents:
 | 
				
			||||||
 | 
					                filtered_labels = [ cls.decompose(label)[0] if freqs.get(label,cutoff) < cutoff else label for label in labels ]
 | 
				
			||||||
 | 
					                filtered_sents.append(((ids,words,tags,heads,filtered_labels,iob), ctnts))
 | 
				
			||||||
 | 
					            filtered.append((raw_text, filtered_sents))
 | 
				
			||||||
 | 
					        return filtered
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,5 +15,6 @@ cdef class ParserModel(AveragedPerceptron):
 | 
				
			||||||
cdef class Parser:
 | 
					cdef class Parser:
 | 
				
			||||||
    cdef readonly ParserModel model
 | 
					    cdef readonly ParserModel model
 | 
				
			||||||
    cdef readonly TransitionSystem moves
 | 
					    cdef readonly TransitionSystem moves
 | 
				
			||||||
 | 
					    cdef int _projectivize
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cdef int parseC(self, TokenC* tokens, int length, int nr_feat, int nr_class) nogil
 | 
					    cdef int parseC(self, TokenC* tokens, int length, int nr_feat, int nr_class) nogil
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,12 +12,12 @@ from cpython.exc cimport PyErr_CheckSignals
 | 
				
			||||||
from libc.stdint cimport uint32_t, uint64_t
 | 
					from libc.stdint cimport uint32_t, uint64_t
 | 
				
			||||||
from libc.string cimport memset, memcpy
 | 
					from libc.string cimport memset, memcpy
 | 
				
			||||||
from libc.stdlib cimport malloc, calloc, free
 | 
					from libc.stdlib cimport malloc, calloc, free
 | 
				
			||||||
import random
 | 
					 | 
				
			||||||
import os.path
 | 
					import os.path
 | 
				
			||||||
from os import path
 | 
					from os import path
 | 
				
			||||||
import shutil
 | 
					import shutil
 | 
				
			||||||
import json
 | 
					import json
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
 | 
					from .nonproj import PseudoProjectivity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from cymem.cymem cimport Pool, Address
 | 
					from cymem.cymem cimport Pool, Address
 | 
				
			||||||
from murmurhash.mrmr cimport hash64
 | 
					from murmurhash.mrmr cimport hash64
 | 
				
			||||||
| 
						 | 
					@ -79,9 +79,10 @@ cdef class ParserModel(AveragedPerceptron):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cdef class Parser:
 | 
					cdef class Parser:
 | 
				
			||||||
    def __init__(self, StringStore strings, transition_system, ParserModel model):
 | 
					    def __init__(self, StringStore strings, transition_system, ParserModel model, int projectivize = 0):
 | 
				
			||||||
        self.moves = transition_system
 | 
					        self.moves = transition_system
 | 
				
			||||||
        self.model = model
 | 
					        self.model = model
 | 
				
			||||||
 | 
					        self._projectivize = projectivize
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def from_dir(cls, model_dir, strings, transition_system):
 | 
					    def from_dir(cls, model_dir, strings, transition_system):
 | 
				
			||||||
| 
						 | 
					@ -93,9 +94,10 @@ cdef class Parser:
 | 
				
			||||||
        moves = transition_system(strings, cfg.labels)
 | 
					        moves = transition_system(strings, cfg.labels)
 | 
				
			||||||
        templates = get_templates(cfg.features)
 | 
					        templates = get_templates(cfg.features)
 | 
				
			||||||
        model = ParserModel(templates)
 | 
					        model = ParserModel(templates)
 | 
				
			||||||
 | 
					        project = cfg.projectivize if hasattr(cfg,'projectivize') else False
 | 
				
			||||||
        if path.exists(path.join(model_dir, 'model')):
 | 
					        if path.exists(path.join(model_dir, 'model')):
 | 
				
			||||||
            model.load(path.join(model_dir, 'model'))
 | 
					            model.load(path.join(model_dir, 'model'))
 | 
				
			||||||
        return cls(strings, moves, model)
 | 
					        return cls(strings, moves, model, project)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def load(cls, pkg_or_str_or_file, vocab):
 | 
					    def load(cls, pkg_or_str_or_file, vocab):
 | 
				
			||||||
| 
						 | 
					@ -114,6 +116,9 @@ cdef class Parser:
 | 
				
			||||||
            tokens.is_parsed = True
 | 
					            tokens.is_parsed = True
 | 
				
			||||||
        # Check for KeyboardInterrupt etc. Untested
 | 
					        # Check for KeyboardInterrupt etc. Untested
 | 
				
			||||||
        PyErr_CheckSignals()
 | 
					        PyErr_CheckSignals()
 | 
				
			||||||
 | 
					        # projectivize output
 | 
				
			||||||
 | 
					        if self._projectivize:
 | 
				
			||||||
 | 
					            PseudoProjectivity.deprojectivize(tokens)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def pipe(self, stream, int batch_size=1000, int n_threads=2):
 | 
					    def pipe(self, stream, int batch_size=1000, int n_threads=2):
 | 
				
			||||||
        cdef Pool mem = Pool()
 | 
					        cdef Pool mem = Pool()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -143,7 +143,7 @@ cdef class Tagger:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def blank(cls, vocab, templates):
 | 
					    def blank(cls, vocab, templates):
 | 
				
			||||||
        model = TaggerModel(N_CONTEXT_FIELDS, templates)
 | 
					        model = TaggerModel(templates)
 | 
				
			||||||
        return cls(vocab, model)
 | 
					        return cls(vocab, model)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
| 
						 | 
					@ -153,10 +153,8 @@ cdef class Tagger:
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def from_package(cls, pkg, vocab):
 | 
					    def from_package(cls, pkg, vocab):
 | 
				
			||||||
        # TODO: templates.json deprecated? not present in latest package
 | 
					        # TODO: templates.json deprecated? not present in latest package
 | 
				
			||||||
        templates = cls.default_templates()
 | 
					        # templates = cls.default_templates()
 | 
				
			||||||
        # templates = package.load_utf8(json.load,
 | 
					        templates = pkg.load_json(('pos', 'templates.json'), default=cls.default_templates())
 | 
				
			||||||
        #     'pos', 'templates.json',
 | 
					 | 
				
			||||||
        #     default=cls.default_templates())
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        model = TaggerModel(templates)
 | 
					        model = TaggerModel(templates)
 | 
				
			||||||
        if pkg.has_file('pos', 'model'):
 | 
					        if pkg.has_file('pos', 'model'):
 | 
				
			||||||
| 
						 | 
					@ -221,7 +219,7 @@ cdef class Tagger:
 | 
				
			||||||
    def train(self, Doc tokens, object gold_tag_strs):
 | 
					    def train(self, Doc tokens, object gold_tag_strs):
 | 
				
			||||||
        assert len(tokens) == len(gold_tag_strs)
 | 
					        assert len(tokens) == len(gold_tag_strs)
 | 
				
			||||||
        for tag in gold_tag_strs:
 | 
					        for tag in gold_tag_strs:
 | 
				
			||||||
            if tag not in self.tag_names:
 | 
					            if tag != None and tag not in self.tag_names:
 | 
				
			||||||
                msg = ("Unrecognized gold tag: %s. tag_map.json must contain all"
 | 
					                msg = ("Unrecognized gold tag: %s. tag_map.json must contain all"
 | 
				
			||||||
                       "gold tags, to maintain coarse-grained mapping.")
 | 
					                       "gold tags, to maintain coarse-grained mapping.")
 | 
				
			||||||
                raise ValueError(msg % tag)
 | 
					                raise ValueError(msg % tag)
 | 
				
			||||||
| 
						 | 
					@ -234,10 +232,9 @@ cdef class Tagger:
 | 
				
			||||||
            nr_feat=self.model.nr_feat)
 | 
					            nr_feat=self.model.nr_feat)
 | 
				
			||||||
        for i in range(tokens.length):
 | 
					        for i in range(tokens.length):
 | 
				
			||||||
            self.model.set_featuresC(&eg.c, tokens.c, i)
 | 
					            self.model.set_featuresC(&eg.c, tokens.c, i)
 | 
				
			||||||
            eg.set_label(golds[i])
 | 
					            eg.costs = [ 1 if golds[i] not in (c, -1) else 0 for c in xrange(eg.nr_class) ]
 | 
				
			||||||
            self.model.set_scoresC(eg.c.scores,
 | 
					            self.model.set_scoresC(eg.c.scores,
 | 
				
			||||||
                eg.c.features, eg.c.nr_feat)
 | 
					                eg.c.features, eg.c.nr_feat)
 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            self.model.updateC(&eg.c)
 | 
					            self.model.updateC(&eg.c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            self.vocab.morphology.assign_tag(&tokens.c[i], eg.guess)
 | 
					            self.vocab.morphology.assign_tag(&tokens.c[i], eg.guess)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										136
									
								
								spacy/tests/parser/test_nonproj.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								spacy/tests/parser/test_nonproj.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,136 @@
 | 
				
			||||||
 | 
					from __future__ import unicode_literals
 | 
				
			||||||
 | 
					import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from spacy.attrs import DEP, HEAD
 | 
				
			||||||
 | 
					import numpy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from spacy.syntax.nonproj import ancestors, contains_cycle, is_nonproj_arc, is_nonproj_tree, PseudoProjectivity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_ancestors():
 | 
				
			||||||
 | 
						tree = [1,2,2,4,5,2,2]
 | 
				
			||||||
 | 
						cyclic_tree = [1,2,2,4,5,3,2]
 | 
				
			||||||
 | 
						partial_tree = [1,2,2,4,5,None,2]
 | 
				
			||||||
 | 
						multirooted_tree = [3,2,0,3,3,7,7,3,7,10,7,10,11,12,18,16,18,17,12,3]
 | 
				
			||||||
 | 
						assert([ a for a in ancestors(3,tree) ] == [4,5,2])
 | 
				
			||||||
 | 
						assert([ a for a in ancestors(3,cyclic_tree) ] == [4,5,3,4,5,3,4])
 | 
				
			||||||
 | 
						assert([ a for a in ancestors(3,partial_tree) ] == [4,5,None])
 | 
				
			||||||
 | 
						assert([ a for a in ancestors(17,multirooted_tree) ] == [])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_contains_cycle():
 | 
				
			||||||
 | 
						tree = [1,2,2,4,5,2,2]
 | 
				
			||||||
 | 
						cyclic_tree = [1,2,2,4,5,3,2]
 | 
				
			||||||
 | 
						partial_tree = [1,2,2,4,5,None,2]
 | 
				
			||||||
 | 
						multirooted_tree = [3,2,0,3,3,7,7,3,7,10,7,10,11,12,18,16,18,17,12,3]
 | 
				
			||||||
 | 
						assert(contains_cycle(tree) == None)
 | 
				
			||||||
 | 
						assert(contains_cycle(cyclic_tree) == set([3,4,5]))
 | 
				
			||||||
 | 
						assert(contains_cycle(partial_tree) == None)
 | 
				
			||||||
 | 
						assert(contains_cycle(multirooted_tree) == None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_is_nonproj_arc():
 | 
				
			||||||
 | 
						nonproj_tree = [1,2,2,4,5,2,7,4,2]
 | 
				
			||||||
 | 
						partial_tree = [1,2,2,4,5,None,7,4,2]
 | 
				
			||||||
 | 
						multirooted_tree = [3,2,0,3,3,7,7,3,7,10,7,10,11,12,18,16,18,17,12,3]
 | 
				
			||||||
 | 
						assert(is_nonproj_arc(0,nonproj_tree) == False)
 | 
				
			||||||
 | 
						assert(is_nonproj_arc(1,nonproj_tree) == False)
 | 
				
			||||||
 | 
						assert(is_nonproj_arc(2,nonproj_tree) == False)
 | 
				
			||||||
 | 
						assert(is_nonproj_arc(3,nonproj_tree) == False)
 | 
				
			||||||
 | 
						assert(is_nonproj_arc(4,nonproj_tree) == False)
 | 
				
			||||||
 | 
						assert(is_nonproj_arc(5,nonproj_tree) == False)
 | 
				
			||||||
 | 
						assert(is_nonproj_arc(6,nonproj_tree) == False)
 | 
				
			||||||
 | 
						assert(is_nonproj_arc(7,nonproj_tree) == True)
 | 
				
			||||||
 | 
						assert(is_nonproj_arc(8,nonproj_tree) == False)
 | 
				
			||||||
 | 
						assert(is_nonproj_arc(7,partial_tree) == False)
 | 
				
			||||||
 | 
						assert(is_nonproj_arc(17,multirooted_tree) == False)
 | 
				
			||||||
 | 
						assert(is_nonproj_arc(16,multirooted_tree) == True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_is_nonproj_tree():
 | 
				
			||||||
 | 
						proj_tree = [1,2,2,4,5,2,7,5,2]
 | 
				
			||||||
 | 
						nonproj_tree = [1,2,2,4,5,2,7,4,2]
 | 
				
			||||||
 | 
						partial_tree = [1,2,2,4,5,None,7,4,2]
 | 
				
			||||||
 | 
						multirooted_tree = [3,2,0,3,3,7,7,3,7,10,7,10,11,12,18,16,18,17,12,3]
 | 
				
			||||||
 | 
						assert(is_nonproj_tree(proj_tree) == False)
 | 
				
			||||||
 | 
						assert(is_nonproj_tree(nonproj_tree) == True)
 | 
				
			||||||
 | 
						assert(is_nonproj_tree(partial_tree) == False)
 | 
				
			||||||
 | 
						assert(is_nonproj_tree(multirooted_tree) == True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def deprojectivize(proj_heads, deco_labels, EN):
 | 
				
			||||||
 | 
						slen = len(proj_heads)
 | 
				
			||||||
 | 
						sent = EN.tokenizer.tokens_from_list(['whatever'] * slen)
 | 
				
			||||||
 | 
						rel_proj_heads = [ head-i for i,head in enumerate(proj_heads) ]
 | 
				
			||||||
 | 
						labelids = [ EN.vocab.strings[label] for label in deco_labels ]
 | 
				
			||||||
 | 
						parse = numpy.asarray(zip(rel_proj_heads,labelids), dtype=numpy.int32)	
 | 
				
			||||||
 | 
						sent.from_array([HEAD,DEP],parse)
 | 
				
			||||||
 | 
						PseudoProjectivity.deprojectivize(sent)
 | 
				
			||||||
 | 
						parse = sent.to_array([HEAD,DEP])
 | 
				
			||||||
 | 
						deproj_heads = [ i+head for i,head in enumerate(parse[:,0]) ]
 | 
				
			||||||
 | 
						undeco_labels = [ EN.vocab.strings[int(labelid)] for labelid in parse[:,1] ]
 | 
				
			||||||
 | 
						return deproj_heads, undeco_labels
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@pytest.mark.models
 | 
				
			||||||
 | 
					def test_pseudoprojectivity(EN):
 | 
				
			||||||
 | 
						tree = [1,2,2]
 | 
				
			||||||
 | 
						nonproj_tree = [1,2,2,4,5,2,7,4,2]
 | 
				
			||||||
 | 
						labels = ['det','nsubj','root','det','dobj','aux','nsubj','acl','punct']
 | 
				
			||||||
 | 
						nonproj_tree2 = [9,1,3,1,5,6,9,8,6,1,6,12,13,10,1]
 | 
				
			||||||
 | 
						labels2 = ['advmod','root','det','nsubj','advmod','det','dobj','det','nmod','aux','nmod','advmod','det','amod','punct']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert(PseudoProjectivity.decompose('X||Y') == ('X','Y'))
 | 
				
			||||||
 | 
						assert(PseudoProjectivity.decompose('X') == ('X',''))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert(PseudoProjectivity.is_decorated('X||Y') == True)
 | 
				
			||||||
 | 
						assert(PseudoProjectivity.is_decorated('X') == False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						PseudoProjectivity._lift(0,tree)
 | 
				
			||||||
 | 
						assert(tree == [2,2,2])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						np_arc = PseudoProjectivity._get_smallest_nonproj_arc(nonproj_tree)
 | 
				
			||||||
 | 
						assert(np_arc == 7)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						np_arc = PseudoProjectivity._get_smallest_nonproj_arc(nonproj_tree2)
 | 
				
			||||||
 | 
						assert(np_arc == 10)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						proj_heads, deco_labels = PseudoProjectivity.projectivize(nonproj_tree,labels)
 | 
				
			||||||
 | 
						assert(proj_heads == [1,2,2,4,5,2,7,5,2])
 | 
				
			||||||
 | 
						assert(deco_labels == ['det','nsubj','root','det','dobj','aux','nsubj','acl||dobj','punct'])
 | 
				
			||||||
 | 
						deproj_heads, undeco_labels = deprojectivize(proj_heads,deco_labels,EN)
 | 
				
			||||||
 | 
						assert(deproj_heads == nonproj_tree)
 | 
				
			||||||
 | 
						assert(undeco_labels == labels)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						proj_heads, deco_labels = PseudoProjectivity.projectivize(nonproj_tree2,labels2)
 | 
				
			||||||
 | 
						assert(proj_heads == [1,1,3,1,5,6,9,8,6,1,9,12,13,10,1])
 | 
				
			||||||
 | 
						assert(deco_labels == ['advmod||aux','root','det','nsubj','advmod','det','dobj','det','nmod','aux','nmod||dobj','advmod','det','amod','punct'])
 | 
				
			||||||
 | 
						deproj_heads, undeco_labels = deprojectivize(proj_heads,deco_labels,EN)
 | 
				
			||||||
 | 
						assert(deproj_heads == nonproj_tree2)
 | 
				
			||||||
 | 
						assert(undeco_labels == labels2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# if decoration is wrong such that there is no head with the desired label
 | 
				
			||||||
 | 
						# the structure is kept and the label is undecorated
 | 
				
			||||||
 | 
						proj_heads = [1,2,2,4,5,2,7,5,2]
 | 
				
			||||||
 | 
						deco_labels = ['det','nsubj','root','det','dobj','aux','nsubj','acl||iobj','punct']
 | 
				
			||||||
 | 
						deproj_heads, undeco_labels = deprojectivize(proj_heads,deco_labels,EN)
 | 
				
			||||||
 | 
						assert(deproj_heads == proj_heads)
 | 
				
			||||||
 | 
						assert(undeco_labels == ['det','nsubj','root','det','dobj','aux','nsubj','acl','punct'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# if there are two potential new heads, the first one is chosen even if it's wrong
 | 
				
			||||||
 | 
						proj_heads = [1,1,3,1,5,6,9,8,6,1,9,12,13,10,1]
 | 
				
			||||||
 | 
						deco_labels = ['advmod||aux','root','det','aux','advmod','det','dobj','det','nmod','aux','nmod||dobj','advmod','det','amod','punct']
 | 
				
			||||||
 | 
						deproj_heads, undeco_labels = deprojectivize(proj_heads,deco_labels,EN)
 | 
				
			||||||
 | 
						assert(deproj_heads == [3,1,3,1,5,6,9,8,6,1,6,12,13,10,1])
 | 
				
			||||||
 | 
						assert(undeco_labels == ['advmod','root','det','aux','advmod','det','dobj','det','nmod','aux','nmod','advmod','det','amod','punct'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -201,17 +201,9 @@ cdef class Token:
 | 
				
			||||||
            cdef int nr_iter = 0
 | 
					            cdef int nr_iter = 0
 | 
				
			||||||
            cdef const TokenC* ptr = self.c - (self.i - self.c.l_edge)
 | 
					            cdef const TokenC* ptr = self.c - (self.i - self.c.l_edge)
 | 
				
			||||||
            while ptr < self.c:
 | 
					            while ptr < self.c:
 | 
				
			||||||
                # If this head is still to the right of us, we can skip to it
 | 
					                if ptr + ptr.head == self.c:
 | 
				
			||||||
                # No token that's between this token and this head could be our
 | 
					 | 
				
			||||||
                # child.
 | 
					 | 
				
			||||||
                if (ptr.head >= 1) and (ptr + ptr.head) < self.c:
 | 
					 | 
				
			||||||
                    ptr += ptr.head
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                elif ptr + ptr.head == self.c:
 | 
					 | 
				
			||||||
                    yield self.doc[ptr - (self.c - self.i)]
 | 
					                    yield self.doc[ptr - (self.c - self.i)]
 | 
				
			||||||
                ptr += 1
 | 
					                ptr += 1
 | 
				
			||||||
                else:
 | 
					 | 
				
			||||||
                    ptr += 1
 | 
					 | 
				
			||||||
                nr_iter += 1
 | 
					                nr_iter += 1
 | 
				
			||||||
                # This is ugly, but it's a way to guard out infinite loops
 | 
					                # This is ugly, but it's a way to guard out infinite loops
 | 
				
			||||||
                if nr_iter >= 10000000:
 | 
					                if nr_iter >= 10000000:
 | 
				
			||||||
| 
						 | 
					@ -226,16 +218,10 @@ cdef class Token:
 | 
				
			||||||
            tokens = []
 | 
					            tokens = []
 | 
				
			||||||
            cdef int nr_iter = 0
 | 
					            cdef int nr_iter = 0
 | 
				
			||||||
            while ptr > self.c:
 | 
					            while ptr > self.c:
 | 
				
			||||||
                # If this head is still to the right of us, we can skip to it
 | 
					                if ptr + ptr.head == self.c:
 | 
				
			||||||
                # No token that's between this token and this head could be our
 | 
					 | 
				
			||||||
                # child.
 | 
					 | 
				
			||||||
                if (ptr.head < 0) and ((ptr + ptr.head) > self.c):
 | 
					 | 
				
			||||||
                    ptr += ptr.head
 | 
					 | 
				
			||||||
                elif ptr + ptr.head == self.c:
 | 
					 | 
				
			||||||
                    tokens.append(self.doc[ptr - (self.c - self.i)])
 | 
					                    tokens.append(self.doc[ptr - (self.c - self.i)])
 | 
				
			||||||
                ptr -= 1
 | 
					                ptr -= 1
 | 
				
			||||||
                else:
 | 
					                nr_iter += 1
 | 
				
			||||||
                    ptr -= 1
 | 
					 | 
				
			||||||
                if nr_iter >= 10000000:
 | 
					                if nr_iter >= 10000000:
 | 
				
			||||||
                    raise RuntimeError(
 | 
					                    raise RuntimeError(
 | 
				
			||||||
                        "Possibly infinite loop encountered while looking for token.rights")
 | 
					                        "Possibly infinite loop encountered while looking for token.rights")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user