示例#1
0
def save_tree(tree, d, name, postscript=False, **kwargs):
    drawable_tree = tree if d is None else get_drawable_tree(tree[0], d)
    extension = 'ps' if postscript else 'png'
    cf = CanvasFrame()
    tc = TreeWidget(cf.canvas(), drawable_tree)
    tc['node_font'] = 'arial 22 bold'
    tc['leaf_font'] = 'arial 22'
    tc['node_color'] = '#005990'
    tc['leaf_color'] = '#3F8F57'
    tc['line_color'] = '#175252'
    tc['xspace'] = 20
    tc['yspace'] = 20
    curr_y = 40 * len(kwargs)
    cf.add_widget(tc, 0, curr_y)
    cf.print_to_file('{0}.{1}'.format(name, extension))
    if not postscript:
        im1 = Image.open('{0}.{1}'.format(name, extension))
        im1 = im1.convert('RGB')
        curr_y = 10
        for key in kwargs:
            font = ImageFont.truetype("/fonts/Ubuntu-L.ttf", 24)
            draw = ImageDraw.Draw(im1)
            val = kwargs[key]
            format_str = '{0}'
            if isinstance(val, float):
                format_str = format_str + '={1:.4f}'
            else:
                format_str = format_str + '=  {1}'
            draw.text((10, curr_y), format_str.format(key, val), (0, 0, 0),
                      font)
            curr_y = curr_y + 40
        im1.save('{}.pdf'.format(name))
        cf.destroy()
        os.remove('{0}.{1}'.format(name, extension))
    return '{0}.{1}'.format(name, 'ps' if postscript else 'pdf')
示例#2
0
def draw_tree_to_file(tree, path):
    cf = CanvasFrame()
    tc = TreeWidget(cf.canvas(), tree)
    x, y = 0, 0
    cf.add_widget(tc, x, y)
    cf.print_to_file(path)
    cf.destroy()
示例#3
0
def quicktree(sentence):
    """Parse a sentence and return a visual representation in IPython"""
    import os
    from nltk import Tree
    from nltk.draw.util import CanvasFrame
    from nltk.draw import TreeWidget
    from stat_parser import Parser
    try:
        from IPython.display import display
        from IPython.display import Image
    except:
        pass
    try:
        get_ipython().getoutput()
    except TypeError:
        have_ipython = True
    except NameError:
        import subprocess
        have_ipython = False
    parser = Parser()
    parsed = parser.parse(sentence)
    cf = CanvasFrame()
    tc = TreeWidget(cf.canvas(), parsed)
    cf.add_widget(tc, 10, 10)  # (10,10) offsets
    cf.print_to_file('tree.ps')
    cf.destroy()
    if have_ipython:
        tregex_command = 'convert tree.ps tree.png'
        result = get_ipython().getoutput(tregex_command)
    else:
        tregex_command = ["convert", "tree.ps", "tree.png"]
        result = subprocess.check_output(tregex_command)
    os.remove("tree.ps")
    return Image(filename='tree.png')
    os.remove("tree.png")
示例#4
0
def save_tree(tree):
    cf = CanvasFrame()
    tc = TreeWidget(cf.canvas(),tree)
    cf.add_widget(tc,10,10) # (10,10) offsets
    cf.print_to_file('tree.ps')
    cf.destroy()
    os.system('convert tree.ps output.png')
def jupyter_draw_nltk_tree(tree: Tree = None,
                           directory: str = '/tmp',
                           f_name: str = 'tmp',
                           show_tree: bool = False):
    f_name = Path(directory) / f_name
    f_name.parent.mkdir(exist_ok=True, parents=True)

    cf = CanvasFrame()
    tc = TreeWidget(cf.canvas(), tree)
    tc['node_font'] = 'arial 13 bold'
    tc['leaf_font'] = 'arial 14'
    tc['node_color'] = '#005990'
    tc['leaf_color'] = '#3F8F57'
    tc['line_color'] = '#175252'

    cf.add_widget(tc, 20, 20)
    ps_file_name = f_name.with_suffix('.ps').as_posix()
    cf.print_to_file(ps_file_name)
    cf.destroy()

    png_file_name = f_name.with_suffix(".png").as_posix()
    system(f'convert {ps_file_name} {png_file_name}')

    if show_tree:
        display((Image(filename=png_file_name), ))

    system(f'rm {f_name}.ps')

    return png_file_name
示例#6
0
def format(sentence):
    filename = 'stanford-parser.jar'
    command = ['locate', filename]
    output = subprocess.Popen(command, stdout=subprocess.PIPE).communicate()[0]
    path_to_jar = output.decode().strip()

    filename = 'models.jar'
    command = ['locate', filename]
    output = subprocess.Popen(
        command, stdout=subprocess.PIPE).communicate()[0].decode().strip()
    output = output.split('\n')
    for op in output:
        if 'parse' in op:
            path_to_models_jar = op

    dependency_parser = StanfordDependencyParser(
        path_to_jar=path_to_jar, path_to_models_jar=path_to_models_jar)
    tokens = word_tokenize(sentence)
    result = dependency_parser.raw_parse(sentence)

    for dep in result:
        # print(dep.tree())
        cf = CanvasFrame()
        t = dep.tree()
        tc = TreeWidget(cf.canvas(), t)
        cf.add_widget(tc, 10, 10)  # (10,10) offsets
        cf.print_to_file('tree.ps')
        cf.destroy()
        return (dep, tokens)
示例#7
0
def quicktree(sentence):
    """Parse a sentence and return a visual representation in IPython"""
    import os
    from nltk import Tree
    from nltk.draw.util import CanvasFrame
    from nltk.draw import TreeWidget
    from stat_parser import Parser
    try:
        from IPython.display import display
        from IPython.display import Image
    except:
        pass
    try:
        get_ipython().getoutput()
    except TypeError:
        have_ipython = True
    except NameError:
        import subprocess
        have_ipython = False
    parser = Parser()
    parsed = parser.parse(sentence)
    cf = CanvasFrame()
    tc = TreeWidget(cf.canvas(),parsed)
    cf.add_widget(tc,10,10) # (10,10) offsets
    cf.print_to_file('tree.ps')
    cf.destroy()
    if have_ipython:
        tregex_command = 'convert tree.ps tree.png'
        result = get_ipython().getoutput(tregex_command)
    else:
        tregex_command = ["convert", "tree.ps", "tree.png"]
        result = subprocess.check_output(tregex_command)    
    os.remove("tree.ps")
    return Image(filename='tree.png')
    os.remove("tree.png")
def draw_to_file(tree):
    canvas = CanvasFrame()
    tree_canvas = TreeWidget(canvas.canvas(), tree)
    canvas.add_widget(tree_canvas, 10, 10)

    file_name = 'tree_plot.ps'

    canvas.print_to_file(file_name)
    canvas.destroy()
示例#9
0
文件: tree.py 项目: steve3p0/LING511
    def write_tree_stream(self, nltk_tree):
        """
        Draws and outputs in PNG for ipython.
        PNG is used instead of PDF, since it can be displayed in the qt console and
        has wider browser support.
        """
        import os
        import base64
        import subprocess
        import tempfile
        from nltk.draw.tree import tree_to_treesegment
        from nltk.draw.util import CanvasFrame
        from nltk.internals import find_binary

        _canvas_frame = CanvasFrame()
        # widget = tree_to_treesegment(_canvas_frame.canvas(), self)
        widget = tree_to_treesegment(_canvas_frame.canvas(), nltk_tree)
        _canvas_frame.add_widget(widget)
        x, y, w, h = widget.bbox()
        # print_to_file uses scrollregion to set the width and height of the pdf.
        _canvas_frame.canvas()["scrollregion"] = (0, 0, w, h)
        with tempfile.NamedTemporaryFile() as file:
            in_path = "{0:}.ps".format(file.name)
            out_path = "{0:}.png".format(file.name)
            _canvas_frame.print_to_file(in_path)
            _canvas_frame.destroy_widget(widget)
            try:
                subprocess.call([
                    find_binary(
                        "gs",
                        binary_names=["gswin32c.exe", "gswin64c.exe"],
                        env_vars=["PATH"],
                        verbose=False,
                    )
                ] + "-q -dEPSCrop -sDEVICE=png16m -r90 -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -dSAFER -dBATCH -dNOPAUSE -sOutputFile={0:} {1:}"
                                .format(out_path, in_path).split())
            except LookupError:
                pre_error_message = str(
                    "The Ghostscript executable isn't found.\n"
                    "See http://web.mit.edu/ghostscript/www/Install.htm\n"
                    "If you're using a Mac, you can try installing\n"
                    "https://docs.brew.sh/Installation then `brew install ghostscript`"
                )
                print(pre_error_message, file=sys.stderr)
                raise LookupError

            with open(out_path, "rb") as sr:
                res = sr.read()
                b = bytearray(res)
                # b0 = b[0]
            os.remove(in_path)
            os.remove(out_path)
            # return base64.b64encode(res).decode()
            # return base64.b64encode(res)

            # return b0
            return b
示例#10
0
class TreeView:
    def __init__(self, trees, root=None):
        if len(trees) == 0:
            print "No trees to display."
            return

        newroot = False
        if root is None:
            root = Tkinter.Tk()
            window = root
            newroot = True
        else:
            window = Tkinter.Toplevel(root)

        window.title("Parse Tree")
        window.geometry("600x400")
        self.cf = CanvasFrame(window)
        self.cf.pack(side='top', expand=1, fill='both')
        buttons = Tkinter.Frame(window)
        buttons.pack(side='bottom', fill='x')

        self.spin = Tkinter.Spinbox(buttons,
                                    from_=1,
                                    to=len(trees),
                                    command=self.showtree,
                                    width=3)
        if len(trees) > 1: self.spin.pack(side='left')
        self.label = Tkinter.Label(buttons, text="of %d" % len(trees))
        if len(trees) > 1: self.label.pack(side='left')
        self.done = Tkinter.Button(buttons,
                                   text="Done",
                                   command=window.destroy)
        self.done.pack(side='right')
        self.printps = Tkinter.Button(buttons,
                                      text="Print to Postscript",
                                      command=self.cf.print_to_file)
        self.printps.pack(side='right')

        self.trees = trees
        self.treeWidget = None
        self.showtree()
        if newroot: root.mainloop()

    def showtree(self):
        try:
            n = int(self.spin.get())
        except ValueError:
            n = 1
        if self.treeWidget is not None: self.cf.destroy_widget(self.treeWidget)
        self.treeWidget = TreeWidget(self.cf.canvas(),
                                     self.trees[n - 1],
                                     draggable=1,
                                     shapeable=1)
        self.cf.add_widget(self.treeWidget, 0, 0)
def draw_nltk_tree(tree):
    cf = CanvasFrame()
    tc = TreeWidget(cf.canvas(), tree)
    tc['node_font'] = 'arial 15 bold'
    tc['leaf_font'] = 'arial 15'
    tc['node_color'] = '#005990'
    tc['leaf_color'] = '#3F8F57'
    tc['line_color'] = '#175252'
    cf.add_widget(tc, 50, 50)
    cf.print_to_file('tmp_tree_output.ps')
    cf.destroy()
示例#12
0
def drawrst(strtree, fname):
    """ Draw RST tree into a file
    """
    if not fname.endswith(".ps"):
        fname += ".ps"
    cf = CanvasFrame()
    t = Tree.fromstring(strtree)
    tc = TreeWidget(cf.canvas(), t)
    cf.add_widget(tc,10,10) # (10,10) offsets
    cf.print_to_file(fname)
    cf.destroy()
示例#13
0
def draw_tree(tree_string):
    raise NotImplementedError()

    from nltk import Tree
    from nltk.draw.util import CanvasFrame
    from nltk.draw import TreeWidget

    cf = CanvasFrame()
    tree = Tree.fromstring(tree_string.replace('[','(').replace(']',')') )
    cf.add_widget(TreeWidget(cf.canvas(), tree), 10, 10)
    cf.print_to_file('tree.ps')
    cf.destroy
示例#14
0
 def draw_rst(self, fname):
     """ Draw RST tree into a file
     """
     tree_str = self.get_parse()
     if not fname.endswith(".ps"):
         fname += ".ps"
     cf = CanvasFrame()
     t = Tree.fromstring(tree_str)
     tc = TreeWidget(cf.canvas(), t)
     cf.add_widget(tc, 10, 10)  # (10,10) offsets
     cf.print_to_file(fname)
     cf.destroy()
示例#15
0
def save_tree_with_ps(str_tree, save_path):
	# 输出可视化结果
	cf = CanvasFrame()
	tc = TreeWidget(cf.canvas(), str_tree)
	tc['node_font'] = 'arial 14 bold'
	tc['leaf_font'] = 'arial 14'
	tc['node_color'] = '#005990'
	tc['leaf_color'] = '#3F8F57'
	tc['line_color'] = '#175252'
	cf.add_widget(tc, 10, 10) # (10,10) offsets
	cf.print_to_file('{}.ps'.format(save_path))
	cf.destroy()
 def draw_nltk_tree(tree):
     cf = CanvasFrame()
     tc = TreeWidget(cf.canvas(), tree)
     tc['node_font'] = 'arial 15 bold'
     tc['leaf_font'] = 'arial 15'
     tc['node_color'] = '#005990'
     tc['leaf_color'] = '#3F8F57'
     tc['line_color'] = '#175252'
     cf.add_widget(tc, 50, 50)
     cf.print_to_file('tmp_tree_output.ps')
     cf.destroy()
     os.system('convert tmp_tree_output.ps tmp_tree_output.png')
     display(Image(filename='tmp_tree_output.png'))
示例#17
0
def show_tree(treetok):
    cf = CanvasFrame(width=1000, height=450, closeenough=2)
    tc = TreeWidget(cf.canvas(),
                    treetok,
                    draggable=1,
                    node_font=('helvetica', -14, 'bold'),
                    leaf_font=('helvetica', -12, 'italic'),
                    roof_fill='white',
                    roof_color='black',
                    leaf_color='green4',
                    node_color='blue2')
    cf.add_widget(tc, 10, 10)
    cf.mainloop()
示例#18
0
def drawTreeAndSaveImage(s, i, dir):
    parsed_sent = parser.raw_parse(s)
    for line in parsed_sent:
        cf = CanvasFrame()
        t = Tree.fromstring(str(line))
        tc = TreeWidget(cf.canvas(), t)
        cf.add_widget(tc, 10, 10)
        i += 1
        cf.print_to_file(dir + str(i) + '.ps')
        tree_name = dir + str(i) + '.ps'
        tree_new_name = dir + str(i) + '.png'
        os.system('convert ' + tree_name + ' ' + tree_new_name)
        cf.destroy()
def quicktree(sentence):
    """Parse a sentence and return a visual representation"""
    from nltk import Tree
    from nltk.draw.util import CanvasFrame
    from nltk.draw import TreeWidget
    from stat_parser import Parser
    from IPython.display import display
    from IPython.display import Image
    parser = Parser()
    parsed = parser.parse(sentence)
    cf = CanvasFrame()
    tc = TreeWidget(cf.canvas(), parsed)
    cf.add_widget(tc, 10, 10)  # (10,10) offsets
    cf.print_to_file('tree.ps')
    cf.destroy()
示例#20
0
def save_tree(str_tree, save_path):
	# 输出可视化结果
	cf = CanvasFrame()
	tc = TreeWidget(cf.canvas(), str_tree)
	tc['node_font'] = 'arial 14 bold'
	tc['leaf_font'] = 'arial 14'
	tc['node_color'] = '#005990'
	tc['leaf_color'] = '#3F8F57'
	tc['line_color'] = '#175252'
	cf.add_widget(tc, 10, 10) # (10,10) offsets
	cf.print_to_file('tmp.ps')
	cf.destroy()

	# 使用ImageMagick工具进行转换
	lake.shell.run('convert tmp.ps %s' % save_path)
	lake.shell.run('rm tmp.ps')
示例#21
0
文件: draw.py 项目: eipiplusun/educe
def main(args):
    """
    Subcommand main.

    You shouldn't need to call this yourself if you're using
    `config_argparser`
    """
    corpus = read_corpus(args)
    odir = get_output_dir(args)
    for key in corpus:
        cframe = CanvasFrame()
        widget = TreeWidget(cframe.canvas(), corpus[key])
        cframe.add_widget(widget, 10, 10)
        ofilename = fp.join(odir, key.doc) + '.ps'
        cframe.print_to_file(ofilename)
        cframe.destroy()
    announce_output_dir(odir)
示例#22
0
def display_tree(tree):
    if nltk_is_available:
        count = 0
        for t in tree:
            cf = CanvasFrame()
            tc = TreeWidget(cf.canvas(), t)
            cf.add_widget(tc, 10, 10)
            count += 1
            fileName = "tree" + repr(count) + ".ps"
            cf.print_to_file(fileName)
            cf.destroy()
    else:
        count = 0
        for t in tree:
            count += 1
            fileName = "tree" + repr(count) + ".txt"
            pprint.pprint(t, fileName)
def draw_nltk_tree(tree):
    # Borrowed from
    # https://stackoverflow.com/questions/31779707/how-do-you-make-nltk-draw-trees-that-are-inline-in-ipython-jupyter

    cf = CanvasFrame()
    tc = TreeWidget(cf.canvas(), tree)
    tc['node_font'] = 'arial 15 bold'
    tc['leaf_font'] = 'arial 15'
    tc['node_color'] = '#005990'
    tc['leaf_color'] = '#3F8F57'
    tc['line_color'] = '#175252'
    cf.add_widget(tc, 50, 50)
    cf.print_to_file('tmp_tree_output.ps')
    cf.destroy()
    os.system('convert tmp_tree_output.ps tmp_tree_output.png')
    display(Image(filename='tmp_tree_output.png'))
    os.system('rm tmp_tree_output.ps tmp_tree_output.png')
示例#24
0
def main(args):
    """
    Subcommand main.

    You shouldn't need to call this yourself if you're using
    `config_argparser`
    """
    corpus = read_corpus(args)
    odir = get_output_dir(args)
    for key in corpus:
        cframe = CanvasFrame()
        widget = TreeWidget(cframe.canvas(), corpus[key])
        cframe.add_widget(widget, 10, 10)
        ofilename = fp.join(odir, key.doc) + '.ps'
        cframe.print_to_file(ofilename)
        cframe.destroy()
    announce_output_dir(odir)
示例#25
0
	def execute(self, frase):

		os.environ['STANFORD_PARSER'] = 'nltk/stanford-parser.jar'
		os.environ['STANFORD_MODELS'] = 'nltk/stanford-parser-3.5.2-models.jar'

		parser = stanford.StanfordParser(model_path="nltk/englishPCFG.ser.gz")
		sentence = parser.raw_parse(frase)
		print sentence

		# GUI
		for line in sentence:
			cf = CanvasFrame()
			tc = TreeWidget(cf.canvas(),line)
			cf.add_widget(tc,40,40) # (10,10) offsets
			cf.print_to_file('tree_stanford.ps')
			#cf.destroy()
			os.popen('convert tree_stanford.ps -resize 300% static/img/tree_stanford.png')
示例#26
0
def format(sentence, jar_location):
    path_to_jar = jar_location + '/stanford-parser.jar'
    path_to_models_jar = jar_location + '/stanford-parser-3.9.2-models.jar'

    dependency_parser = StanfordDependencyParser(
        path_to_jar=path_to_jar, path_to_models_jar=path_to_models_jar)
    tokens = word_tokenize(sentence)
    result = dependency_parser.raw_parse(sentence)

    for dep in result:
        # print(dep.tree())
        cf = CanvasFrame()
        t = dep.tree()
        tc = TreeWidget(cf.canvas(), t)
        cf.add_widget(tc, 10, 10)
        cf.print_to_file('tree.ps')
        cf.destroy()
        return (dep, tokens)
示例#27
0
def draw_trees(trees, name, reverse_dict=None, print_prob=False):
    for ind, tree in enumerate(trees):
        if reverse_dict:
            change_leaves(tree[0], reverse_dict)
        in_row = 1
        len_one = 140
        height = 200
        i = 0
        cf = CanvasFrame()
        tc = TreeWidget(cf.canvas(), tree[0])
        x, y = (i % in_row) * len_one, int(i / in_row) * height
        cf.add_widget(tc, x, y)
        if print_prob:
            tp = TreeWidget(cf.canvas(), tree[1])
            cf.add_widget(tp, x + len_one, y)
        i = i + 1
        cf.print_to_file('{0}{1}.ps'.format(name, ind))
        cf.destroy()
示例#28
0
	def tagger(self, frase):
		#hacer el tag
		text = nltk.word_tokenize(frase)
		postag = nltk.pos_tag(text)

		#convertirlo al formato lips
		result = "("
		
		for index in range(len(postag)):
			result +=  "( " + postag[index][0] + " ( " + postag[index][1]+ " ) )"

		result += ")"

		#ejecutar bikel

		#pasar resultado a archivo
		#hoy = str(datetime.date.today())

		f = open('prueba', 'w')
		f.write(result)
		f.close()
		
		#consola = os.popen('tcsh ../dbparser/bin/parse 400 ../dbparser/settings/collins.properties ../wsj-02-21.obj.gz prueba')

		args = shlex.split("tcsh ../dbparser/bin/parse 400 ../dbparser/settings/collins.properties ../wsj-02-21.obj.gz prueba")
		print args

		p = subprocess.Popen(args,stderr=subprocess.STDOUT)
		p.wait()

		f2 = open('prueba.parsed', 'r')
		resultado = f2.read()

		t = Tree.fromstring(resultado)

		cf = CanvasFrame()
		tc = TreeWidget(cf.canvas(),t)
		cf.add_widget(tc,40,40) # (10,10) offsets
		cf.print_to_file('tree_bikel.ps')
		#cf.destroy()
		os.popen('convert tree_bikel.ps -resize 300% static/img/tree_bikel.png')
		

		return resultado
示例#29
0
def create_tree_ps(parse_tree):
    cf = CanvasFrame(width=550, height=450, closeenough=2)

    t = Tree.fromstring(parse_tree)

    tc = TreeWidget(
        cf.canvas(),
        t,
        draggable=1,
        node_font=("helvetica", -14, "bold"),
        leaf_font=("helvetica", -12, "italic"),
        roof_fill="white",
        roof_color="black",
        leaf_color="green4",
        node_color="blue2",
    )
    cf.add_widget(tc, 10, 10)

    cf.print_to_file(constants.QIK_DATA_DIR + "query_parse_tree.ps")
示例#30
0
class TreeView:
    def __init__(self, trees, root=None):
        if len(trees) == 0:
            print "No trees to display."
            return

        newroot = False
        if root is None:
            root = Tkinter.Tk()
            window = root
            newroot = True
        else:
            window = Tkinter.Toplevel(root)
        
        window.title("Parse Tree")
        window.geometry("600x400")
        self.cf = CanvasFrame(window)
        self.cf.pack(side='top', expand=1, fill='both')
        buttons = Tkinter.Frame(window)
        buttons.pack(side='bottom', fill='x')

        self.spin = Tkinter.Spinbox(buttons, from_=1, to=len(trees),
            command=self.showtree, width=3)
        if len(trees) > 1: self.spin.pack(side='left')
        self.label = Tkinter.Label(buttons, text="of %d" % len(trees))
        if len(trees) > 1: self.label.pack(side='left')
        self.done = Tkinter.Button(buttons, text="Done", command=window.destroy)
        self.done.pack(side='right')
        self.printps = Tkinter.Button(buttons, text="Print to Postscript", command=self.cf.print_to_file)
        self.printps.pack(side='right')
        
        self.trees = trees
        self.treeWidget = None
        self.showtree()
        if newroot: root.mainloop()
    
    def showtree(self):
        try: n = int(self.spin.get())
        except ValueError: n=1
        if self.treeWidget is not None: self.cf.destroy_widget(self.treeWidget)
        self.treeWidget = TreeWidget(self.cf.canvas(),
        self.trees[n-1], draggable=1, shapeable=1)
        self.cf.add_widget(self.treeWidget, 0, 0)
示例#31
0
def generar_arbol(gramatica, cadena_input, funcion_split, graficar=False):

    cadena = funcion_split(cadena_input)

    arboles = gramatica_to_arbol(gramatica, cadena)

    if graficar:

        cf = CanvasFrame()

        for arbol in arboles:

            file_name = str(uuid.uuid4())

            tc = TreeWidget(cf.canvas(), arbol)

            tc['node_font'] = 'arial 10 bold'
            tc['leaf_font'] = 'arial 10'
            tc['node_color'] = '#005990'
            tc['leaf_color'] = '#3F8F57'
            tc['line_color'] = '#175252'

            cf.add_widget(tc)

            cf.canvas().update()

            # Bug si hay parentesis en los terminales de la gramatica
            t = Tree.fromstring(str(arbol))

            TreeView(t)._cframe.print_to_file('./res/{}.ps'.format(file_name))

            # No funciona en windows
            try:
                generar_png(file_name)
            except Exception as ex:
                print(ex)

        cf.mainloop()

    if arboles:
        return True
    else:
        return False
示例#32
0
def tree_to_ps(s, outfile):
    global _canvas_frame
    if _canvas_frame is None:
        _canvas_frame = CanvasFrame()

    # May throw ValueError:
    widget = tree_to_widget(s, _canvas_frame.canvas())

    _canvas_frame.canvas()['scrollregion'] = (0, 0, 1, 1)
    _canvas_frame.add_widget(widget)
    _canvas_frame.print_to_file(outfile)
    bbox = widget.bbox()
    _canvas_frame.destroy_widget(widget)

    ## Testing..
    #for (key, val) in metrics.items():
    #    print key, '\n  ', val

    return bbox[2:]
示例#33
0
def tree_to_ps(s, outfile):
    global _canvas_frame
    if _canvas_frame is None:
        _canvas_frame = CanvasFrame()

    # May throw ValueError:
    widget = tree_to_widget(s, _canvas_frame.canvas())

    _canvas_frame.canvas()['scrollregion'] = (0, 0, 1, 1)
    _canvas_frame.add_widget(widget)
    _canvas_frame.print_to_file(outfile)
    bbox = widget.bbox()
    _canvas_frame.destroy_widget(widget)

    ## Testing..
    #for (key, val) in metrics.items():
    #    print key, '\n  ', val
    
    return bbox[2:]
示例#34
0
    def convertPsToPng(self, treeVal):
        cf = CanvasFrame()

        tr = Tree.fromstring(treeVal)
        tc = TreeWidget(cf.canvas(), tr)

        tc['node_font'] = 'arial 13 bold'
        tc['leaf_font'] = 'arial 11'
        tc['node_color'] = '#005990'
        tc['leaf_color'] = '#3F8F57'
        tc['line_color'] = '#175252'
        tc['xspace'] = 25
        tc['yspace'] = 25

        cf.add_widget(tc, 10, 10)  # (10,10) offsets

        cf.print_to_file(self.filenamePS)
        cf.destroy()

        #MagickImage doit etre installée ainsi que convert
        os.system("convert %s %s" % (self.filenamePS, self.filenamePNG))
示例#35
0
    def to_ps(self, filename):
        """Export as a PostScript image.

        This function is used by `_repr_png_`.
        """
        _canvas_frame = CanvasFrame()
        # WIP customization of visual appearance
        # NB: conda-provided python and tk cannot access most fonts on the
        # system, thus it currently falls back on the default font
        widget = tree_to_treesegment(_canvas_frame.canvas(), self,
                                     tree_yspace=35,
                                     node_font=('Verdana', -18, 'bold'),
                                     leaf_font=('Verdana', -18))
        _canvas_frame.add_widget(widget)
        x, y, w, h = widget.bbox()
        # print_to_file uses scrollregion to set the width and height of the
        # pdf
        _canvas_frame.canvas()['scrollregion'] = (0, 0, w, h)
        # print to file
        _canvas_frame.print_to_file(filename)
        _canvas_frame.destroy_widget(widget)
示例#36
0
def save_image(parsed, index: str) -> Binary:
    cf = CanvasFrame()
    tc = TreeWidget(cf.canvas(), parsed, xspace=40, yspace=40)
    tc['node_font'] = 'arial 20 bold'
    tc['leaf_font'] = 'arial 20 bold'
    tc['node_color'] = '#005990'
    tc['leaf_color'] = '#3F8F57'
    tc['line_color'] = '#175252'
    cf.add_widget(tc, 50, 50)

    cf.print_to_file(os.path.join(trees_path, f'tree_{index}.ps'))
    cf.destroy()

    os.system(f'convert {trees_path}/tree_{index}.ps '
              f'{trees_path}/tree_{index}.png')
    os.remove(f'{trees_path}/tree_{index}.ps')

    with open(f'{trees_path}/tree_{index}.png', 'rb') as tree_img:
        tree_bin = Binary(tree_img.read())

    return tree_bin
示例#37
0
def draw_one_tree(strtree, draw_file):
    cf = CanvasFrame()
    t = Tree.fromstring(strtree)
    tc = TreeWidget(cf.canvas(), t, draggable=1)
    cf.add_widget(tc, 1200, 0)  # (10,10) offsets
    # edus 文本
    edus_txt = ""
    c = cf.canvas()
    edu_path = RAW_TXT + "/" + draw_file.split("/")[2].split(
        ".")[0] + ".out.edu"
    with open(edu_path, "r") as f:
        for line in f:
            edus_txt += line
    edus_txt = TextWidget(c, edus_txt, draggable=1)
    cf.add_widget(edus_txt, 1400, 0)
    user_choice = input("直接打印(a) or 存到文件(b): ")
    if user_choice == "a":
        cf.mainloop()
    else:
        cf.print_to_file(draw_file)
        cf.destroy()
示例#38
0
def build_syntax_tree(txt):
    sentences = nltk.sent_tokenize(txt)
    for sent in sentences:
        tsent = pos_tag_sentence(sent, 'tree')
        ch = nltk.RegexpParser(grammar)
        tree = ch.parse(tsent)

        cf = CanvasFrame()
        tc = TreeWidget(cf.canvas(), tree)
        tc['node_font'] = 'arial 14 bold'
        tc['leaf_font'] = 'arial 14'
        tc['node_color'] = '#005990'
        tc['leaf_color'] = '#3F8F57'
        tc['line_color'] = '#175252'
        cf.add_widget(tc, 10, 10)
        cf.print_to_file(path + 'tree.ps')
        cf.destroy()

        os.system('convert {0}tree.ps {0}tree.png'.format(path))

        return open(path + 'tree.png', 'rb')
示例#39
0
def test(parses):
    def fill(cw):
        cw['fill'] = '#%06d' % random.randint(0,999999)

    cf = CanvasFrame(width=550, height=450, closeenough=2)

    j = 10

    for parse in parses:
        t  = Tree.fromstring(parse)
        tc = TreeWidget(cf.canvas(), t, draggable=1,
                    node_font=('helvetica', -14, 'bold'),
                    leaf_font=('helvetica', -12, 'italic'),
                    roof_fill='white', roof_color='black',
                    leaf_color='green4', node_color='blue2')

        cf.add_widget(tc,10,j)
        tc.bind_click_trees(tc.toggle_collapsed)
        j += 500

    # Run mainloop
    cf.mainloop()
示例#40
0
    def to_ps(self, filename):
        """Export as a PostScript image.

        This function is used by `_repr_png_`.
        """
        _canvas_frame = CanvasFrame()
        # WIP customization of visual appearance
        # NB: conda-provided python and tk cannot access most fonts on the
        # system, thus it currently falls back on the default font
        widget = tree_to_treesegment(_canvas_frame.canvas(),
                                     self,
                                     tree_yspace=35,
                                     node_font=('Verdana', -18, 'bold'),
                                     leaf_font=('Verdana', -18))
        _canvas_frame.add_widget(widget)
        x, y, w, h = widget.bbox()
        # print_to_file uses scrollregion to set the width and height of the
        # pdf
        _canvas_frame.canvas()['scrollregion'] = (0, 0, w, h)
        # print to file
        _canvas_frame.print_to_file(filename)
        _canvas_frame.destroy_widget(widget)
示例#41
0
文件: cfg.py 项目: sfu-natlang/nltk
class CFGDemo(object):
    def __init__(self, grammar, text):
        self._grammar = grammar
        self._text = text

        # Set up the main window.
        self._top = Tk()
        self._top.title('Context Free Grammar Demo')

        # Base font size
        self._size = IntVar(self._top)
        self._size.set(12) # = medium

        # Set up the key bindings
        self._init_bindings(self._top)

        # Create the basic frames
        frame1 = Frame(self._top)
        frame1.pack(side='left', fill='y', expand=0)
        self._init_menubar(self._top)
        self._init_buttons(self._top)
        self._init_grammar(frame1)
        self._init_treelet(frame1)
        self._init_workspace(self._top)

    #//////////////////////////////////////////////////
    # Initialization
    #//////////////////////////////////////////////////

    def _init_bindings(self, top):
        top.bind('<Control-q>', self.destroy)

    def _init_menubar(self, parent): pass

    def _init_buttons(self, parent): pass

    def _init_grammar(self, parent):
        self._prodlist = ProductionList(parent, self._grammar, width=20)
        self._prodlist.pack(side='top', fill='both', expand=1)
        self._prodlist.focus()
        self._prodlist.add_callback('select', self._selectprod_cb)
        self._prodlist.add_callback('move', self._selectprod_cb)

    def _init_treelet(self, parent):
        self._treelet_canvas = Canvas(parent, background='white')
        self._treelet_canvas.pack(side='bottom', fill='x')
        self._treelet = None

    def _init_workspace(self, parent):
        self._workspace = CanvasFrame(parent, background='white')
        self._workspace.pack(side='right', fill='both', expand=1)
        self._tree = None
        self.reset_workspace()

    #//////////////////////////////////////////////////
    # Workspace
    #//////////////////////////////////////////////////

    def reset_workspace(self):
        c = self._workspace.canvas()
        fontsize = int(self._size.get())
        node_font = ('helvetica', -(fontsize+4), 'bold')
        leaf_font = ('helvetica', -(fontsize+2))

        # Remove the old tree
        if self._tree is not None:
            self._workspace.remove_widget(self._tree)

        # The root of the tree.
        start = self._grammar.start().symbol()
        rootnode = TextWidget(c, start, font=node_font, draggable=1)

        # The leaves of the tree.
        leaves = []
        for word in self._text:
            leaves.append(TextWidget(c, word, font=leaf_font, draggable=1))

        # Put it all together into one tree
        self._tree = TreeSegmentWidget(c, rootnode, leaves,
                                       color='white')

        # Add it to the workspace.
        self._workspace.add_widget(self._tree)

        # Move the leaves to the bottom of the workspace.
        for leaf in leaves: leaf.move(0,100)

        #self._nodes = {start:1}
        #self._leaves = dict([(l,1) for l in leaves])

    def workspace_markprod(self, production):
        pass

    def _markproduction(self, prod, tree=None):
        if tree is None: tree = self._tree
        for i in range(len(tree.subtrees())-len(prod.rhs())):
            if tree['color', i] == 'white':
                self._markproduction

            for j, node in enumerate(prod.rhs()):
                widget = tree.subtrees()[i+j]
                if (isinstance(node, Nonterminal) and
                    isinstance(widget, TreeSegmentWidget) and
                    node.symbol == widget.label().text()):
                    pass # matching nonterminal
                elif (isinstance(node, compat.string_types) and
                      isinstance(widget, TextWidget) and
                      node == widget.text()):
                    pass # matching nonterminal
                else: break
            else:
                # Everything matched!
                print('MATCH AT', i)

    #//////////////////////////////////////////////////
    # Grammar
    #//////////////////////////////////////////////////

    def _selectprod_cb(self, production):
        canvas = self._treelet_canvas

        self._prodlist.highlight(production)
        if self._treelet is not None: self._treelet.destroy()

        # Convert the production to a tree.
        rhs = production.rhs()
        for (i, elt) in enumerate(rhs):
            if isinstance(elt, Nonterminal): elt = Tree(elt)
        tree = Tree(production.lhs().symbol(), *rhs)

        # Draw the tree in the treelet area.
        fontsize = int(self._size.get())
        node_font = ('helvetica', -(fontsize+4), 'bold')
        leaf_font = ('helvetica', -(fontsize+2))
        self._treelet = tree_to_treesegment(canvas, tree,
                                            node_font=node_font,
                                            leaf_font=leaf_font)
        self._treelet['draggable'] = 1

        # Center the treelet.
        (x1, y1, x2, y2) = self._treelet.bbox()
        w, h = int(canvas['width']), int(canvas['height'])
        self._treelet.move((w-x1-x2)/2, (h-y1-y2)/2)

        # Mark the places where we can add it to the workspace.
        self._markproduction(production)

    def destroy(self, *args):
        self._top.destroy()

    def mainloop(self, *args, **kwargs):
        self._top.mainloop(*args, **kwargs)
示例#42
0
class RecursiveDescentApp(object):
    """
    A graphical tool for exploring the recursive descent parser.  The tool
    displays the parser's tree and the remaining text, and allows the
    user to control the parser's operation.  In particular, the user
    can expand subtrees on the frontier, match tokens on the frontier
    against the text, and backtrack.  A "step" button simply steps
    through the parsing process, performing the operations that
    ``RecursiveDescentParser`` would use.
    """
    def __init__(self, grammar, sent, trace=0):
        self._sent = sent
        self._parser = SteppingRecursiveDescentParser(grammar, trace)

        # Set up the main window.
        self._top = Tk()
        self._top.title('Recursive Descent Parser Application')

        # Set up key bindings.
        self._init_bindings()

        # Initialize the fonts.
        self._init_fonts(self._top)

        # Animations.  animating_lock is a lock to prevent the demo
        # from performing new operations while it's animating.
        self._animation_frames = IntVar(self._top)
        self._animation_frames.set(5)
        self._animating_lock = 0
        self._autostep = 0

        # The user can hide the grammar.
        self._show_grammar = IntVar(self._top)
        self._show_grammar.set(1)

        # Create the basic frames.
        self._init_menubar(self._top)
        self._init_buttons(self._top)
        self._init_feedback(self._top)
        self._init_grammar(self._top)
        self._init_canvas(self._top)

        # Initialize the parser.
        self._parser.initialize(self._sent)

        # Resize callback
        self._canvas.bind('<Configure>', self._configure)

    #########################################
    ##  Initialization Helpers
    #########################################

    def _init_fonts(self, root):
        # See: <http://www.astro.washington.edu/owen/ROTKFolklore.html>
        self._sysfont = tkFont.Font(font=Button()["font"])
        root.option_add("*Font", self._sysfont)

        # TWhat's our font size (default=same as sysfont)
        self._size = IntVar(root)
        self._size.set(self._sysfont.cget('size'))

        self._boldfont = tkFont.Font(family='helvetica', weight='bold',
                                    size=self._size.get())
        self._font = tkFont.Font(family='helvetica',
                                    size=self._size.get())
        if self._size.get() < 0: big = self._size.get()-2
        else: big = self._size.get()+2
        self._bigfont = tkFont.Font(family='helvetica', weight='bold',
                                    size=big)

    def _init_grammar(self, parent):
        # Grammar view.
        self._prodframe = listframe = Frame(parent)
        self._prodframe.pack(fill='both', side='left', padx=2)
        self._prodlist_label = Label(self._prodframe, font=self._boldfont,
                                     text='Available Expansions')
        self._prodlist_label.pack()
        self._prodlist = Listbox(self._prodframe, selectmode='single',
                                 relief='groove', background='white',
                                 foreground='#909090', font=self._font,
                                 selectforeground='#004040',
                                 selectbackground='#c0f0c0')

        self._prodlist.pack(side='right', fill='both', expand=1)

        self._productions = list(self._parser.grammar().productions())
        for production in self._productions:
            self._prodlist.insert('end', ('  %s' % production))
        self._prodlist.config(height=min(len(self._productions), 25))

        # Add a scrollbar if there are more than 25 productions.
        if len(self._productions) > 25:
            listscroll = Scrollbar(self._prodframe,
                                   orient='vertical')
            self._prodlist.config(yscrollcommand = listscroll.set)
            listscroll.config(command=self._prodlist.yview)
            listscroll.pack(side='left', fill='y')

        # If they select a production, apply it.
        self._prodlist.bind('<<ListboxSelect>>', self._prodlist_select)

    def _init_bindings(self):
        # Key bindings are a good thing.
        self._top.bind('<Control-q>', self.destroy)
        self._top.bind('<Control-x>', self.destroy)
        self._top.bind('<Escape>', self.destroy)
        self._top.bind('e', self.expand)
        #self._top.bind('<Alt-e>', self.expand)
        #self._top.bind('<Control-e>', self.expand)
        self._top.bind('m', self.match)
        self._top.bind('<Alt-m>', self.match)
        self._top.bind('<Control-m>', self.match)
        self._top.bind('b', self.backtrack)
        self._top.bind('<Alt-b>', self.backtrack)
        self._top.bind('<Control-b>', self.backtrack)
        self._top.bind('<Control-z>', self.backtrack)
        self._top.bind('<BackSpace>', self.backtrack)
        self._top.bind('a', self.autostep)
        #self._top.bind('<Control-a>', self.autostep)
        self._top.bind('<Control-space>', self.autostep)
        self._top.bind('<Control-c>', self.cancel_autostep)
        self._top.bind('<space>', self.step)
        self._top.bind('<Delete>', self.reset)
        self._top.bind('<Control-p>', self.postscript)
        #self._top.bind('<h>', self.help)
        #self._top.bind('<Alt-h>', self.help)
        self._top.bind('<Control-h>', self.help)
        self._top.bind('<F1>', self.help)
        #self._top.bind('<g>', self.toggle_grammar)
        #self._top.bind('<Alt-g>', self.toggle_grammar)
        #self._top.bind('<Control-g>', self.toggle_grammar)
        self._top.bind('<Control-g>', self.edit_grammar)
        self._top.bind('<Control-t>', self.edit_sentence)

    def _init_buttons(self, parent):
        # Set up the frames.
        self._buttonframe = buttonframe = Frame(parent)
        buttonframe.pack(fill='none', side='bottom', padx=3, pady=2)
        Button(buttonframe, text='Step',
               background='#90c0d0', foreground='black',
               command=self.step,).pack(side='left')
        Button(buttonframe, text='Autostep',
               background='#90c0d0', foreground='black',
               command=self.autostep,).pack(side='left')
        Button(buttonframe, text='Expand', underline=0,
               background='#90f090', foreground='black',
               command=self.expand).pack(side='left')
        Button(buttonframe, text='Match', underline=0,
               background='#90f090', foreground='black',
               command=self.match).pack(side='left')
        Button(buttonframe, text='Backtrack', underline=0,
               background='#f0a0a0', foreground='black',
               command=self.backtrack).pack(side='left')
        # Replace autostep...
#         self._autostep_button = Button(buttonframe, text='Autostep',
#                                        underline=0, command=self.autostep)
#         self._autostep_button.pack(side='left')

    def _configure(self, event):
        self._autostep = 0
        (x1, y1, x2, y2) = self._cframe.scrollregion()
        y2 = event.height - 6
        self._canvas['scrollregion'] = '%d %d %d %d' % (x1,y1,x2,y2)
        self._redraw()

    def _init_feedback(self, parent):
        self._feedbackframe = feedbackframe = Frame(parent)
        feedbackframe.pack(fill='x', side='bottom', padx=3, pady=3)
        self._lastoper_label = Label(feedbackframe, text='Last Operation:',
                                     font=self._font)
        self._lastoper_label.pack(side='left')
        lastoperframe = Frame(feedbackframe, relief='sunken', border=1)
        lastoperframe.pack(fill='x', side='right', expand=1, padx=5)
        self._lastoper1 = Label(lastoperframe, foreground='#007070',
                                background='#f0f0f0', font=self._font)
        self._lastoper2 = Label(lastoperframe, anchor='w', width=30,
                                foreground='#004040', background='#f0f0f0',
                                font=self._font)
        self._lastoper1.pack(side='left')
        self._lastoper2.pack(side='left', fill='x', expand=1)

    def _init_canvas(self, parent):
        self._cframe = CanvasFrame(parent, background='white',
                                   #width=525, height=250,
                                   closeenough=10,
                                   border=2, relief='sunken')
        self._cframe.pack(expand=1, fill='both', side='top', pady=2)
        canvas = self._canvas = self._cframe.canvas()

        # Initially, there's no tree or text
        self._tree = None
        self._textwidgets = []
        self._textline = None

    def _init_menubar(self, parent):
        menubar = Menu(parent)

        filemenu = Menu(menubar, tearoff=0)
        filemenu.add_command(label='Reset Parser', underline=0,
                             command=self.reset, accelerator='Del')
        filemenu.add_command(label='Print to Postscript', underline=0,
                             command=self.postscript, accelerator='Ctrl-p')
        filemenu.add_command(label='Exit', underline=1,
                             command=self.destroy, accelerator='Ctrl-x')
        menubar.add_cascade(label='File', underline=0, menu=filemenu)

        editmenu = Menu(menubar, tearoff=0)
        editmenu.add_command(label='Edit Grammar', underline=5,
                             command=self.edit_grammar,
                             accelerator='Ctrl-g')
        editmenu.add_command(label='Edit Text', underline=5,
                             command=self.edit_sentence,
                             accelerator='Ctrl-t')
        menubar.add_cascade(label='Edit', underline=0, menu=editmenu)

        rulemenu = Menu(menubar, tearoff=0)
        rulemenu.add_command(label='Step', underline=1,
                             command=self.step, accelerator='Space')
        rulemenu.add_separator()
        rulemenu.add_command(label='Match', underline=0,
                             command=self.match, accelerator='Ctrl-m')
        rulemenu.add_command(label='Expand', underline=0,
                             command=self.expand, accelerator='Ctrl-e')
        rulemenu.add_separator()
        rulemenu.add_command(label='Backtrack', underline=0,
                             command=self.backtrack, accelerator='Ctrl-b')
        menubar.add_cascade(label='Apply', underline=0, menu=rulemenu)

        viewmenu = Menu(menubar, tearoff=0)
        viewmenu.add_checkbutton(label="Show Grammar", underline=0,
                                 variable=self._show_grammar,
                                 command=self._toggle_grammar)
        viewmenu.add_separator()
        viewmenu.add_radiobutton(label='Tiny', variable=self._size,
                                 underline=0, value=10, command=self.resize)
        viewmenu.add_radiobutton(label='Small', variable=self._size,
                                 underline=0, value=12, command=self.resize)
        viewmenu.add_radiobutton(label='Medium', variable=self._size,
                                 underline=0, value=14, command=self.resize)
        viewmenu.add_radiobutton(label='Large', variable=self._size,
                                 underline=0, value=18, command=self.resize)
        viewmenu.add_radiobutton(label='Huge', variable=self._size,
                                 underline=0, value=24, command=self.resize)
        menubar.add_cascade(label='View', underline=0, menu=viewmenu)

        animatemenu = Menu(menubar, tearoff=0)
        animatemenu.add_radiobutton(label="No Animation", underline=0,
                                    variable=self._animation_frames,
                                    value=0)
        animatemenu.add_radiobutton(label="Slow Animation", underline=0,
                                    variable=self._animation_frames,
                                    value=10, accelerator='-')
        animatemenu.add_radiobutton(label="Normal Animation", underline=0,
                                    variable=self._animation_frames,
                                    value=5, accelerator='=')
        animatemenu.add_radiobutton(label="Fast Animation", underline=0,
                                    variable=self._animation_frames,
                                    value=2, accelerator='+')
        menubar.add_cascade(label="Animate", underline=1, menu=animatemenu)


        helpmenu = Menu(menubar, tearoff=0)
        helpmenu.add_command(label='About', underline=0,
                             command=self.about)
        helpmenu.add_command(label='Instructions', underline=0,
                             command=self.help, accelerator='F1')
        menubar.add_cascade(label='Help', underline=0, menu=helpmenu)

        parent.config(menu=menubar)

    #########################################
    ##  Helper
    #########################################

    def _get(self, widget, treeloc):
        for i in treeloc: widget = widget.subtrees()[i]
        if isinstance(widget, TreeSegmentWidget):
            widget = widget.node()
        return widget

    #########################################
    ##  Main draw procedure
    #########################################

    def _redraw(self):
        canvas = self._canvas

        # Delete the old tree, widgets, etc.
        if self._tree is not None:
            self._cframe.destroy_widget(self._tree)
        for twidget in self._textwidgets:
            self._cframe.destroy_widget(twidget)
        if self._textline is not None:
            self._canvas.delete(self._textline)

        # Draw the tree.
        helv = ('helvetica', -self._size.get())
        bold = ('helvetica', -self._size.get(), 'bold')
        attribs = {'tree_color': '#000000', 'tree_width': 2,
                   'node_font': bold, 'leaf_font': helv,}
        tree = self._parser.tree()
        self._tree = tree_to_treesegment(canvas, tree, **attribs)
        self._cframe.add_widget(self._tree, 30, 5)

        # Draw the text.
        helv = ('helvetica', -self._size.get())
        bottom = y = self._cframe.scrollregion()[3]
        self._textwidgets = [TextWidget(canvas, word, font=self._font)
                             for word in self._sent]
        for twidget in self._textwidgets:
            self._cframe.add_widget(twidget, 0, 0)
            twidget.move(0, bottom-twidget.bbox()[3]-5)
            y = min(y, twidget.bbox()[1])

        # Draw a line over the text, to separate it from the tree.
        self._textline = canvas.create_line(-5000, y-5, 5000, y-5, dash='.')

        # Highlight appropriate nodes.
        self._highlight_nodes()
        self._highlight_prodlist()

        # Make sure the text lines up.
        self._position_text()


    def _redraw_quick(self):
        # This should be more-or-less sufficient after an animation.
        self._highlight_nodes()
        self._highlight_prodlist()
        self._position_text()

    def _highlight_nodes(self):
        # Highlight the list of nodes to be checked.
        bold = ('helvetica', -self._size.get(), 'bold')
        for treeloc in self._parser.frontier()[:1]:
            self._get(self._tree, treeloc)['color'] = '#20a050'
            self._get(self._tree, treeloc)['font'] = bold
        for treeloc in self._parser.frontier()[1:]:
            self._get(self._tree, treeloc)['color'] = '#008080'

    def _highlight_prodlist(self):
        # Highlight the productions that can be expanded.
        # Boy, too bad tkinter doesn't implement Listbox.itemconfig;
        # that would be pretty useful here.
        self._prodlist.delete(0, 'end')
        expandable = self._parser.expandable_productions()
        untried = self._parser.untried_expandable_productions()
        productions = self._productions
        for index in range(len(productions)):
            if productions[index] in expandable:
                if productions[index] in untried:
                    self._prodlist.insert(index, ' %s' % productions[index])
                else:
                    self._prodlist.insert(index, ' %s (TRIED)' %
                                          productions[index])
                self._prodlist.selection_set(index)
            else:
                self._prodlist.insert(index, ' %s' % productions[index])

    def _position_text(self):
        # Line up the text widgets that are matched against the tree
        numwords = len(self._sent)
        num_matched = numwords - len(self._parser.remaining_text())
        leaves = self._tree_leaves()[:num_matched]
        xmax = self._tree.bbox()[0]
        for i in range(0, len(leaves)):
            widget = self._textwidgets[i]
            leaf = leaves[i]
            widget['color'] = '#006040'
            leaf['color'] = '#006040'
            widget.move(leaf.bbox()[0] - widget.bbox()[0], 0)
            xmax = widget.bbox()[2] + 10

        # Line up the text widgets that are not matched against the tree.
        for i in range(len(leaves), numwords):
            widget = self._textwidgets[i]
            widget['color'] = '#a0a0a0'
            widget.move(xmax - widget.bbox()[0], 0)
            xmax = widget.bbox()[2] + 10

        # If we have a complete parse, make everything green :)
        if self._parser.currently_complete():
            for twidget in self._textwidgets:
                twidget['color'] = '#00a000'

        # Move the matched leaves down to the text.
        for i in range(0, len(leaves)):
            widget = self._textwidgets[i]
            leaf = leaves[i]
            dy = widget.bbox()[1] - leaf.bbox()[3] - 10.0
            dy = max(dy, leaf.parent().node().bbox()[3] - leaf.bbox()[3] + 10)
            leaf.move(0, dy)

    def _tree_leaves(self, tree=None):
        if tree is None: tree = self._tree
        if isinstance(tree, TreeSegmentWidget):
            leaves = []
            for child in tree.subtrees(): leaves += self._tree_leaves(child)
            return leaves
        else:
            return [tree]

    #########################################
    ##  Button Callbacks
    #########################################

    def destroy(self, *e):
        self._autostep = 0
        if self._top is None: return
        self._top.destroy()
        self._top = None

    def reset(self, *e):
        self._autostep = 0
        self._parser.initialize(self._sent)
        self._lastoper1['text'] = 'Reset Application'
        self._lastoper2['text'] = ''
        self._redraw()

    def autostep(self, *e):
        if self._animation_frames.get() == 0:
            self._animation_frames.set(2)
        if self._autostep:
            self._autostep = 0
        else:
            self._autostep = 1
            self._step()

    def cancel_autostep(self, *e):
        #self._autostep_button['text'] = 'Autostep'
        self._autostep = 0

    # Make sure to stop auto-stepping if we get any user input.
    def step(self, *e): self._autostep = 0; self._step()
    def match(self, *e): self._autostep = 0; self._match()
    def expand(self, *e): self._autostep = 0; self._expand()
    def backtrack(self, *e): self._autostep = 0; self._backtrack()

    def _step(self):
        if self._animating_lock: return

        # Try expanding, matching, and backtracking (in that order)
        if self._expand(): pass
        elif self._parser.untried_match() and self._match(): pass
        elif self._backtrack(): pass
        else:
            self._lastoper1['text'] = 'Finished'
            self._lastoper2['text'] = ''
            self._autostep = 0

        # Check if we just completed a parse.
        if self._parser.currently_complete():
            self._autostep = 0
            self._lastoper2['text'] += '    [COMPLETE PARSE]'

    def _expand(self, *e):
        if self._animating_lock: return
        old_frontier = self._parser.frontier()
        rv = self._parser.expand()
        if rv is not None:
            self._lastoper1['text'] = 'Expand:'
            self._lastoper2['text'] = rv
            self._prodlist.selection_clear(0, 'end')
            index = self._productions.index(rv)
            self._prodlist.selection_set(index)
            self._animate_expand(old_frontier[0])
            return 1
        else:
            self._lastoper1['text'] = 'Expand:'
            self._lastoper2['text'] = '(all expansions tried)'
            return 0

    def _match(self, *e):
        if self._animating_lock: return
        old_frontier = self._parser.frontier()
        rv = self._parser.match()
        if rv is not None:
            self._lastoper1['text'] = 'Match:'
            self._lastoper2['text'] = rv
            self._animate_match(old_frontier[0])
            return 1
        else:
            self._lastoper1['text'] = 'Match:'
            self._lastoper2['text'] = '(failed)'
            return 0

    def _backtrack(self, *e):
        if self._animating_lock: return
        if self._parser.backtrack():
            elt = self._parser.tree()
            for i in self._parser.frontier()[0]:
                elt = elt[i]
            self._lastoper1['text'] = 'Backtrack'
            self._lastoper2['text'] = ''
            if isinstance(elt, Tree):
                self._animate_backtrack(self._parser.frontier()[0])
            else:
                self._animate_match_backtrack(self._parser.frontier()[0])
            return 1
        else:
            self._autostep = 0
            self._lastoper1['text'] = 'Finished'
            self._lastoper2['text'] = ''
            return 0

    def about(self, *e):
        ABOUT = ("NLTK Recursive Descent Parser Application\n"+
                 "Written by Edward Loper")
        TITLE = 'About: Recursive Descent Parser Application'
        try:
            from tkMessageBox import Message
            Message(message=ABOUT, title=TITLE).show()
        except:
            ShowText(self._top, TITLE, ABOUT)

    def help(self, *e):
        self._autostep = 0
        # The default font's not very legible; try using 'fixed' instead.
        try:
            ShowText(self._top, 'Help: Recursive Descent Parser Application',
                     (__doc__ or '').strip(), width=75, font='fixed')
        except:
            ShowText(self._top, 'Help: Recursive Descent Parser Application',
                     (__doc__ or '').strip(), width=75)

    def postscript(self, *e):
        self._autostep = 0
        self._cframe.print_to_file()

    def mainloop(self, *args, **kwargs):
        """
        Enter the Tkinter mainloop.  This function must be called if
        this demo is created from a non-interactive program (e.g.
        from a secript); otherwise, the demo will close as soon as
        the script completes.
        """
        if in_idle(): return
        self._top.mainloop(*args, **kwargs)

    def resize(self, size=None):
        if size is not None: self._size.set(size)
        size = self._size.get()
        self._font.configure(size=-(abs(size)))
        self._boldfont.configure(size=-(abs(size)))
        self._sysfont.configure(size=-(abs(size)))
        self._bigfont.configure(size=-(abs(size+2)))
        self._redraw()

    #########################################
    ##  Expand Production Selection
    #########################################

    def _toggle_grammar(self, *e):
        if self._show_grammar.get():
            self._prodframe.pack(fill='both', side='left', padx=2,
                                 after=self._feedbackframe)
            self._lastoper1['text'] = 'Show Grammar'
        else:
            self._prodframe.pack_forget()
            self._lastoper1['text'] = 'Hide Grammar'
        self._lastoper2['text'] = ''

#     def toggle_grammar(self, *e):
#         self._show_grammar = not self._show_grammar
#         if self._show_grammar:
#             self._prodframe.pack(fill='both', expand='y', side='left',
#                                  after=self._feedbackframe)
#             self._lastoper1['text'] = 'Show Grammar'
#         else:
#             self._prodframe.pack_forget()
#             self._lastoper1['text'] = 'Hide Grammar'
#         self._lastoper2['text'] = ''

    def _prodlist_select(self, event):
        selection = self._prodlist.curselection()
        if len(selection) != 1: return
        index = int(selection[0])
        old_frontier = self._parser.frontier()
        production = self._parser.expand(self._productions[index])

        if production:
            self._lastoper1['text'] = 'Expand:'
            self._lastoper2['text'] = production
            self._prodlist.selection_clear(0, 'end')
            self._prodlist.selection_set(index)
            self._animate_expand(old_frontier[0])
        else:
            # Reset the production selections.
            self._prodlist.selection_clear(0, 'end')
            for prod in self._parser.expandable_productions():
                index = self._productions.index(prod)
                self._prodlist.selection_set(index)

    #########################################
    ##  Animation
    #########################################

    def _animate_expand(self, treeloc):
        oldwidget = self._get(self._tree, treeloc)
        oldtree = oldwidget.parent()
        top = not isinstance(oldtree.parent(), TreeSegmentWidget)

        tree = self._parser.tree()
        for i in treeloc:
            tree = tree[i]

        widget = tree_to_treesegment(self._canvas, tree,
                                     node_font=self._boldfont,
                                     leaf_color='white',
                                     tree_width=2, tree_color='white',
                                     node_color='white',
                                     leaf_font=self._font)
        widget.node()['color'] = '#20a050'

        (oldx, oldy) = oldtree.node().bbox()[:2]
        (newx, newy) = widget.node().bbox()[:2]
        widget.move(oldx-newx, oldy-newy)

        if top:
            self._cframe.add_widget(widget, 0, 5)
            widget.move(30-widget.node().bbox()[0], 0)
            self._tree = widget
        else:
            oldtree.parent().replace_child(oldtree, widget)

        # Move the children over so they don't overlap.
        # Line the children up in a strange way.
        if widget.subtrees():
            dx = (oldx + widget.node().width()/2 -
                  widget.subtrees()[0].bbox()[0]/2 -
                  widget.subtrees()[0].bbox()[2]/2)
            for subtree in widget.subtrees(): subtree.move(dx, 0)

        self._makeroom(widget)

        if top:
            self._cframe.destroy_widget(oldtree)
        else:
            oldtree.destroy()

        colors = ['gray%d' % (10*int(10*x/self._animation_frames.get()))
                  for x in range(self._animation_frames.get(),0,-1)]

        # Move the text string down, if necessary.
        dy = widget.bbox()[3] + 30 - self._canvas.coords(self._textline)[1]
        if dy > 0:
            for twidget in self._textwidgets: twidget.move(0, dy)
            self._canvas.move(self._textline, 0, dy)

        self._animate_expand_frame(widget, colors)

    def _makeroom(self, treeseg):
        """
        Make sure that no sibling tree bbox's overlap.
        """
        parent = treeseg.parent()
        if not isinstance(parent, TreeSegmentWidget): return

        index = parent.subtrees().index(treeseg)

        # Handle siblings to the right
        rsiblings = parent.subtrees()[index+1:]
        if rsiblings:
            dx = treeseg.bbox()[2] - rsiblings[0].bbox()[0] + 10
            for sibling in rsiblings: sibling.move(dx, 0)

        # Handle siblings to the left
        if index > 0:
            lsibling = parent.subtrees()[index-1]
            dx = max(0, lsibling.bbox()[2] - treeseg.bbox()[0] + 10)
            treeseg.move(dx, 0)

        # Keep working up the tree.
        self._makeroom(parent)

    def _animate_expand_frame(self, widget, colors):
        if len(colors) > 0:
            self._animating_lock = 1
            widget['color'] = colors[0]
            for subtree in widget.subtrees():
                if isinstance(subtree, TreeSegmentWidget):
                    subtree.node()['color'] = colors[0]
                else:
                    subtree['color'] = colors[0]
            self._top.after(50, self._animate_expand_frame,
                            widget, colors[1:])
        else:
            widget['color'] = 'black'
            for subtree in widget.subtrees():
                if isinstance(subtree, TreeSegmentWidget):
                    subtree.node()['color'] = 'black'
                else:
                    subtree['color'] = 'black'
            self._redraw_quick()
            widget.node()['color'] = 'black'
            self._animating_lock = 0
            if self._autostep: self._step()

    def _animate_backtrack(self, treeloc):
        # Flash red first, if we're animating.
        if self._animation_frames.get() == 0: colors = []
        else: colors = ['#a00000', '#000000', '#a00000']
        colors += ['gray%d' % (10*int(10*x/(self._animation_frames.get())))
                   for x in range(1, self._animation_frames.get()+1)]

        widgets = [self._get(self._tree, treeloc).parent()]
        for subtree in widgets[0].subtrees():
            if isinstance(subtree, TreeSegmentWidget):
                widgets.append(subtree.node())
            else:
                widgets.append(subtree)

        self._animate_backtrack_frame(widgets, colors)

    def _animate_backtrack_frame(self, widgets, colors):
        if len(colors) > 0:
            self._animating_lock = 1
            for widget in widgets: widget['color'] = colors[0]
            self._top.after(50, self._animate_backtrack_frame,
                            widgets, colors[1:])
        else:
            for widget in widgets[0].subtrees():
                widgets[0].remove_child(widget)
                widget.destroy()
            self._redraw_quick()
            self._animating_lock = 0
            if self._autostep: self._step()

    def _animate_match_backtrack(self, treeloc):
        widget = self._get(self._tree, treeloc)
        node = widget.parent().node()
        dy = (1.0 * (node.bbox()[3] - widget.bbox()[1] + 14) /
              max(1, self._animation_frames.get()))
        self._animate_match_backtrack_frame(self._animation_frames.get(),
                                            widget, dy)

    def _animate_match(self, treeloc):
        widget = self._get(self._tree, treeloc)

        dy = ((self._textwidgets[0].bbox()[1] - widget.bbox()[3] - 10.0) /
              max(1, self._animation_frames.get()))
        self._animate_match_frame(self._animation_frames.get(), widget, dy)

    def _animate_match_frame(self, frame, widget, dy):
        if frame > 0:
            self._animating_lock = 1
            widget.move(0, dy)
            self._top.after(10, self._animate_match_frame,
                            frame-1, widget, dy)
        else:
            widget['color'] = '#006040'
            self._redraw_quick()
            self._animating_lock = 0
            if self._autostep: self._step()

    def _animate_match_backtrack_frame(self, frame, widget, dy):
        if frame > 0:
            self._animating_lock = 1
            widget.move(0, dy)
            self._top.after(10, self._animate_match_backtrack_frame,
                            frame-1, widget, dy)
        else:
            widget.parent().remove_child(widget)
            widget.destroy()
            self._animating_lock = 0
            if self._autostep: self._step()

    def edit_grammar(self, *e):
        CFGEditor(self._top, self._parser.grammar(), self.set_grammar)

    def set_grammar(self, grammar):
        self._parser.set_grammar(grammar)
        self._productions = list(grammar.productions())
        self._prodlist.delete(0, 'end')
        for production in self._productions:
            self._prodlist.insert('end', (' %s' % production))

    def edit_sentence(self, *e):
        sentence = " ".join(self._sent)
        title = 'Edit Text'
        instr = 'Enter a new sentence to parse.'
        EntryDialog(self._top, sentence, instr, self.set_sentence, title)

    def set_sentence(self, sentence):
        self._sent = sentence.split() #[XX] use tagged?
        self.reset()
示例#43
0
文件: tree.py 项目: prz3m/kind2anki
def demo():
    import random

    def fill(cw):
        cw['fill'] = '#%06d' % random.randint(0, 999999)

    cf = CanvasFrame(width=550, height=450, closeenough=2)

    t = Tree.fromstring(
        '''
    (S (NP the very big cat)
       (VP (Adv sorta) (V saw) (NP (Det the) (N dog))))'''
    )

    tc = TreeWidget(
        cf.canvas(),
        t,
        draggable=1,
        node_font=('helvetica', -14, 'bold'),
        leaf_font=('helvetica', -12, 'italic'),
        roof_fill='white',
        roof_color='black',
        leaf_color='green4',
        node_color='blue2',
    )
    cf.add_widget(tc, 10, 10)

    def boxit(canvas, text):
        big = ('helvetica', -16, 'bold')
        return BoxWidget(canvas, TextWidget(canvas, text, font=big), fill='green')

    def ovalit(canvas, text):
        return OvalWidget(canvas, TextWidget(canvas, text), fill='cyan')

    treetok = Tree.fromstring('(S (NP this tree) (VP (V is) (AdjP shapeable)))')
    tc2 = TreeWidget(cf.canvas(), treetok, boxit, ovalit, shapeable=1)

    def color(node):
        node['color'] = '#%04d00' % random.randint(0, 9999)

    def color2(treeseg):
        treeseg.label()['fill'] = '#%06d' % random.randint(0, 9999)
        treeseg.label().child()['color'] = 'white'

    tc.bind_click_trees(tc.toggle_collapsed)
    tc2.bind_click_trees(tc2.toggle_collapsed)
    tc.bind_click_nodes(color, 3)
    tc2.expanded_tree(1).bind_click(color2, 3)
    tc2.expanded_tree().bind_click(color2, 3)

    paren = ParenWidget(cf.canvas(), tc2)
    cf.add_widget(paren, tc.bbox()[2] + 10, 10)

    tree3 = Tree.fromstring(
        '''
    (S (NP this tree) (AUX was)
       (VP (V built) (PP (P with) (NP (N tree_to_treesegment)))))'''
    )
    tc3 = tree_to_treesegment(
        cf.canvas(), tree3, tree_color='green4', tree_xspace=2, tree_width=2
    )
    tc3['draggable'] = 1
    cf.add_widget(tc3, 10, tc.bbox()[3] + 10)

    def orientswitch(treewidget):
        if treewidget['orientation'] == 'horizontal':
            treewidget.expanded_tree(1, 1).subtrees()[0].set_text('vertical')
            treewidget.collapsed_tree(1, 1).subtrees()[0].set_text('vertical')
            treewidget.collapsed_tree(1).subtrees()[1].set_text('vertical')
            treewidget.collapsed_tree().subtrees()[3].set_text('vertical')
            treewidget['orientation'] = 'vertical'
        else:
            treewidget.expanded_tree(1, 1).subtrees()[0].set_text('horizontal')
            treewidget.collapsed_tree(1, 1).subtrees()[0].set_text('horizontal')
            treewidget.collapsed_tree(1).subtrees()[1].set_text('horizontal')
            treewidget.collapsed_tree().subtrees()[3].set_text('horizontal')
            treewidget['orientation'] = 'horizontal'

    text = """
Try clicking, right clicking, and dragging
different elements of each of the trees.
The top-left tree is a TreeWidget built from
a Tree.  The top-right is a TreeWidget built
from a Tree, using non-default widget
constructors for the nodes & leaves (BoxWidget
and OvalWidget).  The bottom-left tree is
built from tree_to_treesegment."""
    twidget = TextWidget(cf.canvas(), text.strip())
    textbox = BoxWidget(cf.canvas(), twidget, fill='white', draggable=1)
    cf.add_widget(textbox, tc3.bbox()[2] + 10, tc2.bbox()[3] + 10)

    tree4 = Tree.fromstring('(S (NP this tree) (VP (V is) (Adj horizontal)))')
    tc4 = TreeWidget(
        cf.canvas(),
        tree4,
        draggable=1,
        line_color='brown2',
        roof_color='brown2',
        node_font=('helvetica', -12, 'bold'),
        node_color='brown4',
        orientation='horizontal',
    )
    tc4.manage()
    cf.add_widget(tc4, tc3.bbox()[2] + 10, textbox.bbox()[3] + 10)
    tc4.bind_click(orientswitch)
    tc4.bind_click_trees(tc4.toggle_collapsed, 3)

    # Run mainloop
    cf.mainloop()
示例#44
0
文件: tree.py 项目: gijs/nltk
def demo():
    import random

    def fill(cw):
        cw["fill"] = "#%06d" % random.randint(0, 999999)

    cf = CanvasFrame(width=550, height=450, closeenough=2)

    t = Tree.parse(
        """
    (S (NP the very big cat)
       (VP (Adv sorta) (V saw) (NP (Det the) (N dog))))"""
    )

    tc = TreeWidget(
        cf.canvas(),
        t,
        draggable=1,
        node_font=("helvetica", -14, "bold"),
        leaf_font=("helvetica", -12, "italic"),
        roof_fill="white",
        roof_color="black",
        leaf_color="green4",
        node_color="blue2",
    )
    cf.add_widget(tc, 10, 10)

    def boxit(canvas, text):
        big = ("helvetica", -16, "bold")
        return BoxWidget(canvas, TextWidget(canvas, text, font=big), fill="green")

    def ovalit(canvas, text):
        return OvalWidget(canvas, TextWidget(canvas, text), fill="cyan")

    treetok = Tree.parse("(S (NP this tree) (VP (V is) (AdjP shapeable)))")
    tc2 = TreeWidget(cf.canvas(), treetok, boxit, ovalit, shapeable=1)

    def color(node):
        node["color"] = "#%04d00" % random.randint(0, 9999)

    def color2(treeseg):
        treeseg.node()["fill"] = "#%06d" % random.randint(0, 9999)
        treeseg.node().child()["color"] = "white"

    tc.bind_click_trees(tc.toggle_collapsed)
    tc2.bind_click_trees(tc2.toggle_collapsed)
    tc.bind_click_nodes(color, 3)
    tc2.expanded_tree(1).bind_click(color2, 3)
    tc2.expanded_tree().bind_click(color2, 3)

    paren = ParenWidget(cf.canvas(), tc2)
    cf.add_widget(paren, tc.bbox()[2] + 10, 10)

    tree3 = Tree.parse(
        """
    (S (NP this tree) (AUX was)
       (VP (V built) (PP (P with) (NP (N tree_to_treesegment)))))"""
    )
    tc3 = tree_to_treesegment(cf.canvas(), tree3, tree_color="green4", tree_xspace=2, tree_width=2)
    tc3["draggable"] = 1
    cf.add_widget(tc3, 10, tc.bbox()[3] + 10)

    def orientswitch(treewidget):
        if treewidget["orientation"] == "horizontal":
            treewidget.expanded_tree(1, 1).subtrees()[0].set_text("vertical")
            treewidget.collapsed_tree(1, 1).subtrees()[0].set_text("vertical")
            treewidget.collapsed_tree(1).subtrees()[1].set_text("vertical")
            treewidget.collapsed_tree().subtrees()[3].set_text("vertical")
            treewidget["orientation"] = "vertical"
        else:
            treewidget.expanded_tree(1, 1).subtrees()[0].set_text("horizontal")
            treewidget.collapsed_tree(1, 1).subtrees()[0].set_text("horizontal")
            treewidget.collapsed_tree(1).subtrees()[1].set_text("horizontal")
            treewidget.collapsed_tree().subtrees()[3].set_text("horizontal")
            treewidget["orientation"] = "horizontal"

    text = """
Try clicking, right clicking, and dragging
different elements of each of the trees.
The top-left tree is a TreeWidget built from
a Tree.  The top-right is a TreeWidget built
from a Tree, using non-default widget
constructors for the nodes & leaves (BoxWidget
and OvalWidget).  The bottom-left tree is
built from tree_to_treesegment."""
    twidget = TextWidget(cf.canvas(), text.strip())
    textbox = BoxWidget(cf.canvas(), twidget, fill="white", draggable=1)
    cf.add_widget(textbox, tc3.bbox()[2] + 10, tc2.bbox()[3] + 10)

    tree4 = Tree.parse("(S (NP this tree) (VP (V is) (Adj horizontal)))")
    tc4 = TreeWidget(
        cf.canvas(),
        tree4,
        draggable=1,
        line_color="brown2",
        roof_color="brown2",
        node_font=("helvetica", -12, "bold"),
        node_color="brown4",
        orientation="horizontal",
    )
    tc4.manage()
    cf.add_widget(tc4, tc3.bbox()[2] + 10, textbox.bbox()[3] + 10)
    tc4.bind_click(orientswitch)
    tc4.bind_click_trees(tc4.toggle_collapsed, 3)

    # Run mainloop
    cf.mainloop()
示例#45
0
class ShiftReduceApp(object):
    """
    A graphical tool for exploring the shift-reduce parser.  The tool
    displays the parser's stack and the remaining text, and allows the
    user to control the parser's operation.  In particular, the user
    can shift tokens onto the stack, and can perform reductions on the
    top elements of the stack.  A "step" button simply steps through
    the parsing process, performing the operations that
    ``nltk.parse.ShiftReduceParser`` would use.
    """
    def __init__(self, grammar, sent, trace=0):
        self._sent = sent
        self._parser = SteppingShiftReduceParser(grammar, trace)

        # Set up the main window.
        self._top = Tk()
        self._top.title('Shift Reduce Parser Application')

        # Animations.  animating_lock is a lock to prevent the demo
        # from performing new operations while it's animating.
        self._animating_lock = 0
        self._animate = IntVar(self._top)
        self._animate.set(10) # = medium

        # The user can hide the grammar.
        self._show_grammar = IntVar(self._top)
        self._show_grammar.set(1)

        # Initialize fonts.
        self._init_fonts(self._top)

        # Set up key bindings.
        self._init_bindings()

        # Create the basic frames.
        self._init_menubar(self._top)
        self._init_buttons(self._top)
        self._init_feedback(self._top)
        self._init_grammar(self._top)
        self._init_canvas(self._top)

        # A popup menu for reducing.
        self._reduce_menu = Menu(self._canvas, tearoff=0)

        # Reset the demo, and set the feedback frame to empty.
        self.reset()
        self._lastoper1['text'] = ''

    #########################################
    ##  Initialization Helpers
    #########################################

    def _init_fonts(self, root):
        # See: <http://www.astro.washington.edu/owen/ROTKFolklore.html>
        self._sysfont = tkinter.font.Font(font=Button()["font"])
        root.option_add("*Font", self._sysfont)

        # TWhat's our font size (default=same as sysfont)
        self._size = IntVar(root)
        self._size.set(self._sysfont.cget('size'))

        self._boldfont = tkinter.font.Font(family='helvetica', weight='bold',
                                    size=self._size.get())
        self._font = tkinter.font.Font(family='helvetica',
                                    size=self._size.get())

    def _init_grammar(self, parent):
        # Grammar view.
        self._prodframe = listframe = Frame(parent)
        self._prodframe.pack(fill='both', side='left', padx=2)
        self._prodlist_label = Label(self._prodframe,
                                     font=self._boldfont,
                                     text='Available Reductions')
        self._prodlist_label.pack()
        self._prodlist = Listbox(self._prodframe, selectmode='single',
                                 relief='groove', background='white',
                                 foreground='#909090',
                                 font=self._font,
                                 selectforeground='#004040',
                                 selectbackground='#c0f0c0')

        self._prodlist.pack(side='right', fill='both', expand=1)

        self._productions = list(self._parser.grammar().productions())
        for production in self._productions:
            self._prodlist.insert('end', (' %s' % production))
        self._prodlist.config(height=min(len(self._productions), 25))

        # Add a scrollbar if there are more than 25 productions.
        if 1:#len(self._productions) > 25:
            listscroll = Scrollbar(self._prodframe,
                                   orient='vertical')
            self._prodlist.config(yscrollcommand = listscroll.set)
            listscroll.config(command=self._prodlist.yview)
            listscroll.pack(side='left', fill='y')

        # If they select a production, apply it.
        self._prodlist.bind('<<ListboxSelect>>', self._prodlist_select)

        # When they hover over a production, highlight it.
        self._hover = -1
        self._prodlist.bind('<Motion>', self._highlight_hover)
        self._prodlist.bind('<Leave>', self._clear_hover)

    def _init_bindings(self):
        # Quit
        self._top.bind('<Control-q>', self.destroy)
        self._top.bind('<Control-x>', self.destroy)
        self._top.bind('<Alt-q>', self.destroy)
        self._top.bind('<Alt-x>', self.destroy)

        # Ops (step, shift, reduce, undo)
        self._top.bind('<space>', self.step)
        self._top.bind('<s>', self.shift)
        self._top.bind('<Alt-s>', self.shift)
        self._top.bind('<Control-s>', self.shift)
        self._top.bind('<r>', self.reduce)
        self._top.bind('<Alt-r>', self.reduce)
        self._top.bind('<Control-r>', self.reduce)
        self._top.bind('<Delete>', self.reset)
        self._top.bind('<u>', self.undo)
        self._top.bind('<Alt-u>', self.undo)
        self._top.bind('<Control-u>', self.undo)
        self._top.bind('<Control-z>', self.undo)
        self._top.bind('<BackSpace>', self.undo)

        # Misc
        self._top.bind('<Control-p>', self.postscript)
        self._top.bind('<Control-h>', self.help)
        self._top.bind('<F1>', self.help)
        self._top.bind('<Control-g>', self.edit_grammar)
        self._top.bind('<Control-t>', self.edit_sentence)

        # Animation speed control
        self._top.bind('-', lambda e,a=self._animate:a.set(20))
        self._top.bind('=', lambda e,a=self._animate:a.set(10))
        self._top.bind('+', lambda e,a=self._animate:a.set(4))

    def _init_buttons(self, parent):
        # Set up the frames.
        self._buttonframe = buttonframe = Frame(parent)
        buttonframe.pack(fill='none', side='bottom')
        Button(buttonframe, text='Step',
               background='#90c0d0', foreground='black',
               command=self.step,).pack(side='left')
        Button(buttonframe, text='Shift', underline=0,
               background='#90f090', foreground='black',
               command=self.shift).pack(side='left')
        Button(buttonframe, text='Reduce', underline=0,
               background='#90f090', foreground='black',
               command=self.reduce).pack(side='left')
        Button(buttonframe, text='Undo', underline=0,
               background='#f0a0a0', foreground='black',
               command=self.undo).pack(side='left')

    def _init_menubar(self, parent):
        menubar = Menu(parent)

        filemenu = Menu(menubar, tearoff=0)
        filemenu.add_command(label='Reset Parser', underline=0,
                             command=self.reset, accelerator='Del')
        filemenu.add_command(label='Print to Postscript', underline=0,
                             command=self.postscript, accelerator='Ctrl-p')
        filemenu.add_command(label='Exit', underline=1,
                             command=self.destroy, accelerator='Ctrl-x')
        menubar.add_cascade(label='File', underline=0, menu=filemenu)

        editmenu = Menu(menubar, tearoff=0)
        editmenu.add_command(label='Edit Grammar', underline=5,
                             command=self.edit_grammar,
                             accelerator='Ctrl-g')
        editmenu.add_command(label='Edit Text', underline=5,
                             command=self.edit_sentence,
                             accelerator='Ctrl-t')
        menubar.add_cascade(label='Edit', underline=0, menu=editmenu)

        rulemenu = Menu(menubar, tearoff=0)
        rulemenu.add_command(label='Step', underline=1,
                             command=self.step, accelerator='Space')
        rulemenu.add_separator()
        rulemenu.add_command(label='Shift', underline=0,
                             command=self.shift, accelerator='Ctrl-s')
        rulemenu.add_command(label='Reduce', underline=0,
                             command=self.reduce, accelerator='Ctrl-r')
        rulemenu.add_separator()
        rulemenu.add_command(label='Undo', underline=0,
                             command=self.undo, accelerator='Ctrl-u')
        menubar.add_cascade(label='Apply', underline=0, menu=rulemenu)

        viewmenu = Menu(menubar, tearoff=0)
        viewmenu.add_checkbutton(label="Show Grammar", underline=0,
                                 variable=self._show_grammar,
                                 command=self._toggle_grammar)
        viewmenu.add_separator()
        viewmenu.add_radiobutton(label='Tiny', variable=self._size,
                                 underline=0, value=10, command=self.resize)
        viewmenu.add_radiobutton(label='Small', variable=self._size,
                                 underline=0, value=12, command=self.resize)
        viewmenu.add_radiobutton(label='Medium', variable=self._size,
                                 underline=0, value=14, command=self.resize)
        viewmenu.add_radiobutton(label='Large', variable=self._size,
                                 underline=0, value=18, command=self.resize)
        viewmenu.add_radiobutton(label='Huge', variable=self._size,
                                 underline=0, value=24, command=self.resize)
        menubar.add_cascade(label='View', underline=0, menu=viewmenu)

        animatemenu = Menu(menubar, tearoff=0)
        animatemenu.add_radiobutton(label="No Animation", underline=0,
                                    variable=self._animate, value=0)
        animatemenu.add_radiobutton(label="Slow Animation", underline=0,
                                    variable=self._animate, value=20,
                                    accelerator='-')
        animatemenu.add_radiobutton(label="Normal Animation", underline=0,
                                    variable=self._animate, value=10,
                                    accelerator='=')
        animatemenu.add_radiobutton(label="Fast Animation", underline=0,
                                    variable=self._animate, value=4,
                                    accelerator='+')
        menubar.add_cascade(label="Animate", underline=1, menu=animatemenu)


        helpmenu = Menu(menubar, tearoff=0)
        helpmenu.add_command(label='About', underline=0,
                             command=self.about)
        helpmenu.add_command(label='Instructions', underline=0,
                             command=self.help, accelerator='F1')
        menubar.add_cascade(label='Help', underline=0, menu=helpmenu)

        parent.config(menu=menubar)

    def _init_feedback(self, parent):
        self._feedbackframe = feedbackframe = Frame(parent)
        feedbackframe.pack(fill='x', side='bottom', padx=3, pady=3)
        self._lastoper_label = Label(feedbackframe, text='Last Operation:',
                                     font=self._font)
        self._lastoper_label.pack(side='left')
        lastoperframe = Frame(feedbackframe, relief='sunken', border=1)
        lastoperframe.pack(fill='x', side='right', expand=1, padx=5)
        self._lastoper1 = Label(lastoperframe, foreground='#007070',
                                background='#f0f0f0', font=self._font)
        self._lastoper2 = Label(lastoperframe, anchor='w', width=30,
                                foreground='#004040', background='#f0f0f0',
                                font=self._font)
        self._lastoper1.pack(side='left')
        self._lastoper2.pack(side='left', fill='x', expand=1)

    def _init_canvas(self, parent):
        self._cframe = CanvasFrame(parent, background='white',
                                   width=525, closeenough=10,
                                   border=2, relief='sunken')
        self._cframe.pack(expand=1, fill='both', side='top', pady=2)
        canvas = self._canvas = self._cframe.canvas()

        self._stackwidgets = []
        self._rtextwidgets = []
        self._titlebar = canvas.create_rectangle(0,0,0,0, fill='#c0f0f0',
                                                 outline='black')
        self._exprline = canvas.create_line(0,0,0,0, dash='.')
        self._stacktop = canvas.create_line(0,0,0,0, fill='#408080')
        size = self._size.get()+4
        self._stacklabel = TextWidget(canvas, 'Stack', color='#004040',
                                      font=self._boldfont)
        self._rtextlabel = TextWidget(canvas, 'Remaining Text',
                                      color='#004040', font=self._boldfont)
        self._cframe.add_widget(self._stacklabel)
        self._cframe.add_widget(self._rtextlabel)

    #########################################
    ##  Main draw procedure
    #########################################

    def _redraw(self):
        scrollregion = self._canvas['scrollregion'].split()
        (cx1, cy1, cx2, cy2) = [int(c) for c in scrollregion]

        # Delete the old stack & rtext widgets.
        for stackwidget in self._stackwidgets:
            self._cframe.destroy_widget(stackwidget)
        self._stackwidgets = []
        for rtextwidget in self._rtextwidgets:
            self._cframe.destroy_widget(rtextwidget)
        self._rtextwidgets = []

        # Position the titlebar & exprline
        (x1, y1, x2, y2) = self._stacklabel.bbox()
        y = y2-y1+10
        self._canvas.coords(self._titlebar, -5000, 0, 5000, y-4)
        self._canvas.coords(self._exprline, 0, y*2-10, 5000, y*2-10)

        # Position the titlebar labels..
        (x1, y1, x2, y2) = self._stacklabel.bbox()
        self._stacklabel.move(5-x1, 3-y1)
        (x1, y1, x2, y2) = self._rtextlabel.bbox()
        self._rtextlabel.move(cx2-x2-5, 3-y1)

        # Draw the stack.
        stackx = 5
        for tok in self._parser.stack():
            if isinstance(tok, Tree):
                attribs = {'tree_color': '#4080a0', 'tree_width': 2,
                           'node_font': self._boldfont,
                           'node_color': '#006060',
                           'leaf_color': '#006060', 'leaf_font':self._font}
                widget = tree_to_treesegment(self._canvas, tok,
                                             **attribs)
                widget.label()['color'] = '#000000'
            else:
                widget = TextWidget(self._canvas, tok,
                                    color='#000000', font=self._font)
            widget.bind_click(self._popup_reduce)
            self._stackwidgets.append(widget)
            self._cframe.add_widget(widget, stackx, y)
            stackx = widget.bbox()[2] + 10

        # Draw the remaining text.
        rtextwidth = 0
        for tok in self._parser.remaining_text():
            widget = TextWidget(self._canvas, tok,
                                color='#000000', font=self._font)
            self._rtextwidgets.append(widget)
            self._cframe.add_widget(widget, rtextwidth, y)
            rtextwidth = widget.bbox()[2] + 4

        # Allow enough room to shift the next token (for animations)
        if len(self._rtextwidgets) > 0:
            stackx += self._rtextwidgets[0].width()

        # Move the remaining text to the correct location (keep it
        # right-justified, when possible); and move the remaining text
        # label, if necessary.
        stackx = max(stackx, self._stacklabel.width()+25)
        rlabelwidth = self._rtextlabel.width()+10
        if stackx >= cx2-max(rtextwidth, rlabelwidth):
            cx2 = stackx + max(rtextwidth, rlabelwidth)
        for rtextwidget in self._rtextwidgets:
            rtextwidget.move(4+cx2-rtextwidth, 0)
        self._rtextlabel.move(cx2-self._rtextlabel.bbox()[2]-5, 0)

        midx = (stackx + cx2-max(rtextwidth, rlabelwidth))/2
        self._canvas.coords(self._stacktop, midx, 0, midx, 5000)
        (x1, y1, x2, y2) = self._stacklabel.bbox()

        # Set up binding to allow them to shift a token by dragging it.
        if len(self._rtextwidgets) > 0:
            def drag_shift(widget, midx=midx, self=self):
                if widget.bbox()[0] < midx: self.shift()
                else: self._redraw()
            self._rtextwidgets[0].bind_drag(drag_shift)
            self._rtextwidgets[0].bind_click(self.shift)

        # Draw the stack top.
        self._highlight_productions()

    def _draw_stack_top(self, widget):
        # hack..
        midx = widget.bbox()[2]+50
        self._canvas.coords(self._stacktop, midx, 0, midx, 5000)

    def _highlight_productions(self):
        # Highlight the productions that can be reduced.
        self._prodlist.selection_clear(0, 'end')
        for prod in self._parser.reducible_productions():
            index = self._productions.index(prod)
            self._prodlist.selection_set(index)

    #########################################
    ##  Button Callbacks
    #########################################

    def destroy(self, *e):
        if self._top is None: return
        self._top.destroy()
        self._top = None

    def reset(self, *e):
        self._parser.initialize(self._sent)
        self._lastoper1['text'] = 'Reset App'
        self._lastoper2['text'] = ''
        self._redraw()

    def step(self, *e):
        if self.reduce(): return True
        elif self.shift(): return True
        else:
            if list(self._parser.parses()):
                self._lastoper1['text'] = 'Finished:'
                self._lastoper2['text'] = 'Success'
            else:
                self._lastoper1['text'] = 'Finished:'
                self._lastoper2['text'] = 'Failure'

    def shift(self, *e):
        if self._animating_lock: return
        if self._parser.shift():
            tok = self._parser.stack()[-1]
            self._lastoper1['text'] = 'Shift:'
            self._lastoper2['text'] = '%r' % tok
            if self._animate.get():
                self._animate_shift()
            else:
                self._redraw()
            return True
        return False

    def reduce(self, *e):
        if self._animating_lock: return
        production = self._parser.reduce()
        if production:
            self._lastoper1['text'] = 'Reduce:'
            self._lastoper2['text'] = '%s' % production
            if self._animate.get():
                self._animate_reduce()
            else:
                self._redraw()
        return production

    def undo(self, *e):
        if self._animating_lock: return
        if self._parser.undo():
            self._redraw()

    def postscript(self, *e):
        self._cframe.print_to_file()

    def mainloop(self, *args, **kwargs):
        """
        Enter the Tkinter mainloop.  This function must be called if
        this demo is created from a non-interactive program (e.g.
        from a secript); otherwise, the demo will close as soon as
        the script completes.
        """
        if in_idle(): return
        self._top.mainloop(*args, **kwargs)

    #########################################
    ##  Menubar callbacks
    #########################################

    def resize(self, size=None):
        if size is not None: self._size.set(size)
        size = self._size.get()
        self._font.configure(size=-(abs(size)))
        self._boldfont.configure(size=-(abs(size)))
        self._sysfont.configure(size=-(abs(size)))

        #self._stacklabel['font'] = ('helvetica', -size-4, 'bold')
        #self._rtextlabel['font'] = ('helvetica', -size-4, 'bold')
        #self._lastoper_label['font'] = ('helvetica', -size)
        #self._lastoper1['font'] = ('helvetica', -size)
        #self._lastoper2['font'] = ('helvetica', -size)
        #self._prodlist['font'] = ('helvetica', -size)
        #self._prodlist_label['font'] = ('helvetica', -size-2, 'bold')
        self._redraw()

    def help(self, *e):
        # The default font's not very legible; try using 'fixed' instead.
        try:
            ShowText(self._top, 'Help: Shift-Reduce Parser Application',
                     (__doc__ or '').strip(), width=75, font='fixed')
        except:
            ShowText(self._top, 'Help: Shift-Reduce Parser Application',
                     (__doc__ or '').strip(), width=75)

    def about(self, *e):
        ABOUT = ("NLTK Shift-Reduce Parser Application\n"+
                 "Written by Edward Loper")
        TITLE = 'About: Shift-Reduce Parser Application'
        try:
            from tkinter.messagebox import Message
            Message(message=ABOUT, title=TITLE).show()
        except:
            ShowText(self._top, TITLE, ABOUT)

    def edit_grammar(self, *e):
        CFGEditor(self._top, self._parser.grammar(), self.set_grammar)

    def set_grammar(self, grammar):
        self._parser.set_grammar(grammar)
        self._productions = list(grammar.productions())
        self._prodlist.delete(0, 'end')
        for production in self._productions:
            self._prodlist.insert('end', (' %s' % production))

    def edit_sentence(self, *e):
        sentence = " ".join(self._sent)
        title = 'Edit Text'
        instr = 'Enter a new sentence to parse.'
        EntryDialog(self._top, sentence, instr, self.set_sentence, title)

    def set_sentence(self, sent):
        self._sent = sent.split() #[XX] use tagged?
        self.reset()

    #########################################
    ##  Reduce Production Selection
    #########################################

    def _toggle_grammar(self, *e):
        if self._show_grammar.get():
            self._prodframe.pack(fill='both', side='left', padx=2,
                                 after=self._feedbackframe)
            self._lastoper1['text'] = 'Show Grammar'
        else:
            self._prodframe.pack_forget()
            self._lastoper1['text'] = 'Hide Grammar'
        self._lastoper2['text'] = ''

    def _prodlist_select(self, event):
        selection = self._prodlist.curselection()
        if len(selection) != 1: return
        index = int(selection[0])
        production = self._parser.reduce(self._productions[index])
        if production:
            self._lastoper1['text'] = 'Reduce:'
            self._lastoper2['text'] = '%s' % production
            if self._animate.get():
                self._animate_reduce()
            else:
                self._redraw()
        else:
            # Reset the production selections.
            self._prodlist.selection_clear(0, 'end')
            for prod in self._parser.reducible_productions():
                index = self._productions.index(prod)
                self._prodlist.selection_set(index)

    def _popup_reduce(self, widget):
        # Remove old commands.
        productions = self._parser.reducible_productions()
        if len(productions) == 0: return

        self._reduce_menu.delete(0, 'end')
        for production in productions:
            self._reduce_menu.add_command(label=str(production),
                                          command=self.reduce)
        self._reduce_menu.post(self._canvas.winfo_pointerx(),
                               self._canvas.winfo_pointery())

    #########################################
    ##  Animations
    #########################################

    def _animate_shift(self):
        # What widget are we shifting?
        widget = self._rtextwidgets[0]

        # Where are we shifting from & to?
        right = widget.bbox()[0]
        if len(self._stackwidgets) == 0: left = 5
        else: left = self._stackwidgets[-1].bbox()[2]+10

        # Start animating.
        dt = self._animate.get()
        dx = (left-right)*1.0/dt
        self._animate_shift_frame(dt, widget, dx)

    def _animate_shift_frame(self, frame, widget, dx):
        if frame > 0:
            self._animating_lock = 1
            widget.move(dx, 0)
            self._top.after(10, self._animate_shift_frame,
                            frame-1, widget, dx)
        else:
            # but: stacktop??

            # Shift the widget to the stack.
            del self._rtextwidgets[0]
            self._stackwidgets.append(widget)
            self._animating_lock = 0

            # Display the available productions.
            self._draw_stack_top(widget)
            self._highlight_productions()

    def _animate_reduce(self):
        # What widgets are we shifting?
        numwidgets = len(self._parser.stack()[-1]) # number of children
        widgets = self._stackwidgets[-numwidgets:]

        # How far are we moving?
        if isinstance(widgets[0], TreeSegmentWidget):
            ydist = 15 + widgets[0].label().height()
        else:
            ydist = 15 + widgets[0].height()

        # Start animating.
        dt = self._animate.get()
        dy = ydist*2.0/dt
        self._animate_reduce_frame(dt/2, widgets, dy)

    def _animate_reduce_frame(self, frame, widgets, dy):
        if frame > 0:
            self._animating_lock = 1
            for widget in widgets: widget.move(0, dy)
            self._top.after(10, self._animate_reduce_frame,
                            frame-1, widgets, dy)
        else:
            del self._stackwidgets[-len(widgets):]
            for widget in widgets:
                self._cframe.remove_widget(widget)
            tok = self._parser.stack()[-1]
            if not isinstance(tok, Tree): raise ValueError()
            label = TextWidget(self._canvas, str(tok.label()), color='#006060',
                               font=self._boldfont)
            widget = TreeSegmentWidget(self._canvas, label, widgets,
                                       width=2)
            (x1, y1, x2, y2) = self._stacklabel.bbox()
            y = y2-y1+10
            if not self._stackwidgets: x = 5
            else: x = self._stackwidgets[-1].bbox()[2] + 10
            self._cframe.add_widget(widget, x, y)
            self._stackwidgets.append(widget)

            # Display the available productions.
            self._draw_stack_top(widget)
            self._highlight_productions()

#             # Delete the old widgets..
#             del self._stackwidgets[-len(widgets):]
#             for widget in widgets:
#                 self._cframe.destroy_widget(widget)
#
#             # Make a new one.
#             tok = self._parser.stack()[-1]
#             if isinstance(tok, Tree):
#                 attribs = {'tree_color': '#4080a0', 'tree_width': 2,
#                            'node_font': bold, 'node_color': '#006060',
#                            'leaf_color': '#006060', 'leaf_font':self._font}
#                 widget = tree_to_treesegment(self._canvas, tok.type(),
#                                              **attribs)
#                 widget.node()['color'] = '#000000'
#             else:
#                 widget = TextWidget(self._canvas, tok.type(),
#                                     color='#000000', font=self._font)
#             widget.bind_click(self._popup_reduce)
#             (x1, y1, x2, y2) = self._stacklabel.bbox()
#             y = y2-y1+10
#             if not self._stackwidgets: x = 5
#             else: x = self._stackwidgets[-1].bbox()[2] + 10
#             self._cframe.add_widget(widget, x, y)
#             self._stackwidgets.append(widget)

            #self._redraw()
            self._animating_lock = 0

    #########################################
    ##  Hovering.
    #########################################

    def _highlight_hover(self, event):
        # What production are we hovering over?
        index = self._prodlist.nearest(event.y)
        if self._hover == index: return

        # Clear any previous hover highlighting.
        self._clear_hover()

        # If the production corresponds to an available reduction,
        # highlight the stack.
        selection = [int(s) for s in self._prodlist.curselection()]
        if index in selection:
            rhslen = len(self._productions[index].rhs())
            for stackwidget in self._stackwidgets[-rhslen:]:
                if isinstance(stackwidget, TreeSegmentWidget):
                    stackwidget.label()['color'] = '#00a000'
                else:
                    stackwidget['color'] = '#00a000'

        # Remember what production we're hovering over.
        self._hover = index

    def _clear_hover(self, *event):
        # Clear any previous hover highlighting.
        if self._hover == -1: return
        self._hover = -1
        for stackwidget in self._stackwidgets:
            if isinstance(stackwidget, TreeSegmentWidget):
                stackwidget.label()['color'] = 'black'
            else:
                stackwidget['color'] = 'black'
def demo():
    """
    A demonstration of the probabilistic parsers.  The user is
    prompted to select which demo to run, and how many parses should
    be found; and then each parser is run on the same demo, and a
    summary of the results are displayed.
    """
    import sys, time
    from nltk import tokenize
    from nltk.parse import ViterbiParser
    from nltk.grammar import toy_pcfg1, toy_pcfg2
    from nltk.draw.tree import draw_trees
    from nltk import Tree
    from nltk.draw.util import CanvasFrame
    from nltk.draw import TreeWidget

    # Define two demos.  Each demo has a sentence and a grammar.
    # demos = [('move the green sphere to the bottom left corner', learned_pcfg),
    #          ('move the green ball over the red block', learned_pcfg),
    #          ('take the green pyramid and put it in the top left corner', learned_pcfg),
    #           ('put the green pyramid on the red block', learned_pcfg),
    #           ('move the red cylinder and place it on top of the blue cylinder that is on top of a green cylinder', learned_pcfg),]

    # Ask the user which demo they want to use.
    # print()
    # for i in range(len(demos)):
    #     print('%3s: %s' % (i+1, demos[i][0]))
    #     print('     %r' % demos[i][1])
    #     print()
    # print('Which demo (%d-%d)? ' % (1, len(demos)), end=' ')
    # try:
    #     snum = int(sys.stdin.readline().strip())-1
    #     sent, grammar = demos[snum]
    # except:
    #     print('Bad sentence number')
    #     return

    max_scene = 1

    if max_scene<10:            sc = '0000'+str(max_scene)
    elif max_scene<100:         sc = '000'+str(max_scene)
    elif max_scene<1000:        sc = '00'+str(max_scene)
    elif max_scene<10000:       sc = '0'+str(max_scene)

    g = 'grammar_'+sc+'.txt'
    learned_pcfg = load('/home/omari/Dropbox/robot_modified/AR/grammar/'+g)
    grammar = learned_pcfg

    file1 = open('/home/omari/Dropbox/robot_modified/AR/hypotheses/matched_commands.txt', 'r')
    g1 = [i for i in file1.readlines()]
    for line in g1:
        line = unicode(line,encoding='utf-8')
        sent = line.split('\n')[0].split('-')[-1]
        scene = line.split('\n')[0].split('-')[0]
        sent_num = line.split('\n')[0].split('-')[1]
        print(line)
        if scene == '239' and sent_num == '0':  continue


        # Tokenize the sentence.
        tokens = sent.split()

        parser = ViterbiParser(grammar)
        all_parses = {}

        # print('\nsent: %s\nparser: %s\ngrammar: %s' % (sent,parser,grammar))
        parser.trace(3)
        parses = parser.parse_all(tokens)
        average = (reduce(lambda a,b:a+b.prob(), parses, 0)/len(parses)
                   if parses else 0)
        num_parses = len(parses)
        for p in parses:
            all_parses[p.freeze()] = 1

        # Print some summary statistics
        # print()
        # print('Time (secs)   # Parses   Average P(parse)')
        # print('-----------------------------------------')
        # print('%11.4f%11d%19.14f' % (time, num_parses, average))
        parses = all_parses.keys()
        if parses:
            p = reduce(lambda a,b:a+b.prob(), parses, 0)/len(parses)
        else: p = 0
        # print('------------------------------------------')
        # print('%11s%11d%19.14f' % ('n/a', len(parses), p))

        # Ask the user if we should draw the parses.
        # print()
        # print('Draw parses (y/n)? ', end=' ')
        # if sys.stdin.readline().strip().lower().startswith('y'):

        #     print('  please wait...')
        # draw_trees(*parses)

        cf = CanvasFrame()
        # t = Tree(parses)
        t = Tree.fromstring('(S  (CH_POS_PREPOST move)  (PRE_POST    (PRE      (the the)      (_entity (F_HSV green) (F_SHAPE sphere)))    (PREPOST_connect (to to) (the the))    (POST      (_F_POS (F_POS (_bottom_left (bottom bottom) (left left)))) (corner corner))))')

        tc = TreeWidget(cf.canvas(), t, draggable=1,
                        node_font=('helvetica', -14),
                        leaf_font=('helvetica', -12),
                        roof_fill='white', roof_color='black',
                        leaf_color='green4', node_color='blue4')
        cf.add_widget(tc,10,10)

        # tc = TreeWidget(cf.canvas(),t)
        # cf.add_widget(tc,10,10) # (10,10) offsets
        cf.print_to_file('/home/omari/Dropbox/robot_modified/trees/scene-'+scene+'-'+sent_num+'.ps')
        cf.destroy()
示例#47
0
class CFGDemo(object):
    def __init__(self, grammar, text):
        self._grammar = grammar
        self._text = text

        # Set up the main window.
        self._top = Tk()
        self._top.title('Context Free Grammar Demo')

        # Base font size
        self._size = IntVar(self._top)
        self._size.set(12) # = medium

        # Set up the key bindings
        self._init_bindings(self._top)

        # Create the basic frames
        frame1 = Frame(self._top)
        frame1.pack(side='left', fill='y', expand=0)
        self._init_menubar(self._top)
        self._init_buttons(self._top)
        self._init_grammar(frame1)
        self._init_treelet(frame1)
        self._init_workspace(self._top)

    #//////////////////////////////////////////////////
    # Initialization
    #//////////////////////////////////////////////////

    def _init_bindings(self, top):
        top.bind('<Control-q>', self.destroy)

    def _init_menubar(self, parent): pass

    def _init_buttons(self, parent): pass

    def _init_grammar(self, parent):
        self._prodlist = ProductionList(parent, self._grammar, width=20)
        self._prodlist.pack(side='top', fill='both', expand=1)
        self._prodlist.focus()
        self._prodlist.add_callback('select', self._selectprod_cb)
        self._prodlist.add_callback('move', self._selectprod_cb)

    def _init_treelet(self, parent):
        self._treelet_canvas = Canvas(parent, background='white')
        self._treelet_canvas.pack(side='bottom', fill='x')
        self._treelet = None

    def _init_workspace(self, parent):
        self._workspace = CanvasFrame(parent, background='white')
        self._workspace.pack(side='right', fill='both', expand=1)
        self._tree = None
        self.reset_workspace()

    #//////////////////////////////////////////////////
    # Workspace
    #//////////////////////////////////////////////////

    def reset_workspace(self):
        c = self._workspace.canvas()
        fontsize = int(self._size.get())
        node_font = ('helvetica', -(fontsize+4), 'bold')
        leaf_font = ('helvetica', -(fontsize+2))

        # Remove the old tree
        if self._tree is not None:
            self._workspace.remove_widget(self._tree)

        # The root of the tree.
        start = self._grammar.start().symbol()
        rootnode = TextWidget(c, start, font=node_font, draggable=1)

        # The leaves of the tree.
        leaves = []
        for word in self._text:
            leaves.append(TextWidget(c, word, font=leaf_font, draggable=1))

        # Put it all together into one tree
        self._tree = TreeSegmentWidget(c, rootnode, leaves,
                                       color='white')

        # Add it to the workspace.
        self._workspace.add_widget(self._tree)

        # Move the leaves to the bottom of the workspace.
        for leaf in leaves: leaf.move(0,100)

        #self._nodes = {start:1}
        #self._leaves = dict([(l,1) for l in leaves])

    def workspace_markprod(self, production):
        pass

    def _markproduction(self, prod, tree=None):
        if tree is None: tree = self._tree
        for i in range(len(tree.subtrees())-len(prod.rhs())):
            if tree['color', i] == 'white':
                self._markproduction

            for j, node in enumerate(prod.rhs()):
                widget = tree.subtrees()[i+j]
                if (isinstance(node, Nonterminal) and
                    isinstance(widget, TreeSegmentWidget) and
                    node.symbol == widget.node().text()):
                    pass # matching nonterminal
                elif (isinstance(node, (str, unicode)) and
                      isinstance(widget, TextWidget) and
                     
from nltk import Tree
from nltk.draw.util import CanvasFrame
from nltk.draw import TreeWidget

cf = CanvasFrame()
t = Tree('(S  (CH_POS_PREPOST move)  (PRE_POST    (PRE      (the the)      (_entity (F_HSV green) (F_SHAPE sphere)))    (PREPOST_connect (to to) (the the))    (POST      (_F_POS (F_POS (_bottom_left (bottom bottom) (left left)))) (corner corner))))')
tc = TreeWidget(cf.canvas(),t)
cf.add_widget(tc,10,10) # (10,10) offsets
cf.print_to_file('/home/omari/Dropbox/robot_modified/trees/test.ps')
cf.destroy()
示例#49
0
    return np.mean(np.array(res))




senna_server = Pyro4.Proxy("PYRONAME:servers.senna")

treetok1 = get_parsetree(senna_server.tag(sentence1), sentence1)
treetok2 = get_parsetree(senna_server.tag(sentence2), sentence2)

# show parsetree
cf = CanvasFrame(width=550, height=450, closeenough=2)
tc1 = TreeWidget(cf.canvas(), treetok1, draggable=1,
                node_font=('helvetica', -14, 'bold'),
                leaf_font=('helvetica', -12, 'italic'),
                roof_fill='white', roof_color='black',
                leaf_color='green4', node_color='blue2')
tc2 = TreeWidget(cf.canvas(), treetok2, draggable=1,
                node_font=('helvetica', -14, 'bold'),
                leaf_font=('helvetica', -12, 'italic'),
                roof_fill='white', roof_color='black',
                leaf_color='green4', node_color='blue2')

cf.add_widget(tc1,10,10)
cf.add_widget(tc2,290,10)
cf.mainloop()




{<NOUN><IN><ADJ><NOUN>}
{<ADJ><NOUN><IN><NOUN>}
{<NOUN><IN><NOUN>} # 名词+介词+名词
ADV_ADJ:{<RB><ADJ>} # 副词+形容词
ADJ_PREP_NOUN:{<ADJ><IN><NOUN>} # 形容词+介词+名词
"""

cp = nltk.RegexpParser(grammar)

if len(sys.argv) < 2:
    sys.exit(0)

for s in sys.argv[1:]:
    print('*****************************')
    print(s)
    tags = nltk.pos_tag(nltk.word_tokenize(s))
    tree = nltk.chunk.ne_chunk(tags)
    print(str(tree))
    cf = CanvasFrame()
    tc = TreeWidget(cf.canvas(), tree)
    cf.add_widget(tc, 10, 10)
    cf.print_to_file(s+'.1.ps')
    cf.destroy()
    tree = cp.parse(tags)

    print(str(tree))
    cf = CanvasFrame()
    tc = TreeWidget(cf.canvas(), tree)
    cf.add_widget(tc, 10, 10)
    cf.print_to_file(s+'.2.ps')
class TTFrame():    # Tree Transformation Frame
    def __init__(self,parent=None,index=0,trees=list(),
                 readonly=False):
        self._trees = trees
        self._i_range = len(self._trees)
        self._bold = ('helvetica', -12, 'bold')
        self._helv = ('helvetica', -12)
        if parent is None:
            self._parent = Tk()            
        else:
            self._parent = parent
        t1 = 'Syntagrus - Brandeis - Tree Transformation'
        self._parent.title(t1)
        self._parent.columnconfigure(0,weight=1)
        self._parent.rowconfigure(0,weight=1)


        self._m_f = ttk.Frame(self._parent)
        self._m_f.grid(column=0,row=0,sticky=(N,W,E,S))
        self._m_f.columnconfigure(0,weight=1)
        self._m_f.rowconfigure(1,weight=1)


        self._i_f = ttk.Frame(self._m_f)
        self._i_f.grid(column=0,row=0,sticky=(N,W,E,S))
        self._i_f.columnconfigure(0,weight=1)
        self._i_f.columnconfigure(7,weight=1)

        self._o_p = ttk.Panedwindow(self._m_f,
                                    orient=VERTICAL)
        self._o_p.grid(column=0,row=1,sticky=(N,W,E,S))


        t2 = 'Please enter the index (0-' + \
             str(self._i_range-1) + ')'
        self._i_l = ttk.Label(self._i_f,text=t2)
        self._i_l.grid(column=1,row=0,columnspan=3,
                       sticky=(N,W,E,S))
        self._i_l['anchor'] = 'center'

        self._index = StringVar()
        self._index.set(index)
        self._i_e = ttk.Entry(self._i_f,width=5,
                              textvariable=self._index)
        self._i_e.grid(column=1,row=1,sticky=(N,W,E,S))
        if readonly:
            self._i_e['state']='readonly'

        self._i_b = ttk.Button(self._i_f,width=5,
                    text='Draw',command=self._draw)
        self._i_b.grid(column=3,row=1,sticky=(N,W,E,S))

        self._extra_label = ttk.Label(self._i_f,text='   ')
        self._extra_label.grid(column=4,row=0,rowspan=2,
                               sticky=(N,W,E,S))

        self._var_1 = IntVar()
        self._i_cb_1 = ttk.Checkbutton(self._i_f,
                       text='Transformation 1',
                       variable=self._var_1)
        self._i_cb_1.grid(column=5,row=0,sticky=(N,W,E,S))
        self._var_2 = IntVar()
        self._i_cb_2 = ttk.Checkbutton(self._i_f,
                       text='Transformation 2',
                       variable=self._var_2)
        self._i_cb_2.grid(column=5,row=1,sticky=(N,W,E,S))
        self._var_3 = IntVar()
        self._i_cb_3 = ttk.Checkbutton(self._i_f,
                       text='Transformation 3',
                       variable=self._var_3)
        self._i_cb_3.grid(column=6,row=0,sticky=(N,W,E,S))
        self._var_4 = IntVar()
        self._i_cb_4 = ttk.Checkbutton(self._i_f,
                       text='Transformation 4',
                       variable=self._var_4)
        self._i_cb_4.grid(column=6,row=1,sticky=(N,W,E,S))


        n = 250
        self._o_f_1 = ttk.Labelframe(self._o_p,
                      text='Original',width=n,height=n)
        self._o_f_2 = ttk.Labelframe(self._o_p,
                      text='Transformed',width=n,height=n)
        self._o_p.add(self._o_f_1)
        self._o_p.add(self._o_f_2)


        self._o_cf_1 = CanvasFrame(parent=self._o_f_1,
                                   width=n*2.5,height=n)
        self._o_cf_1.pack(expand=1,fill='both')
        self._o_cf_2 = CanvasFrame(parent=self._o_f_2,
                                   width=n*2.5,height=n)
        self._o_cf_2.pack(expand=1,fill='both')


        self._i_e.focus()
        self._parent.bind('<Return>',self._draw)
        self._parent.mainloop()



    def _draw_tree(self,cf,t):
        return TreeWidget(cf.canvas(),
                          t,
                          node_font=self._bold,
                          leaf_color='#008040',
                          node_color='#004080',
                          roof_color='#004040',
                          roof_fill='white',
                          line_color='#004040',
                          draggable=1,
                          leaf_font=self._helv) 

    def _draw(self,*arg):    
        self._o_cf_1.canvas().delete('all')
        self._o_cf_2.canvas().delete('all')    
        try:
            i = int(self._index.get())
            if i in range(self._i_range):
                original = self._draw_tree(self._o_cf_1,
                                           self._trees[i])
                self._o_cf_1.add_widget(original,10,10)
                if sum([self._var_1.get(),
                        self._var_2.get(),
                        self._var_3.get(),
                        self._var_4.get()]):
                    temp = deepcopy(self._trees[i])
                    if self._var_1.get():
                        change_label(temp,'SBD','SBAR')
                    if self._var_2.get():
                        transform_relative_structures(temp)
                    if self._var_3.get():
                        transform_np2p_structures(temp)
                    if self._var_4.get():
                        transform_coordinative_structures(temp)
                    transformed = self._draw_tree(self._o_cf_2,
                                                  temp)
                    self._o_cf_2.add_widget(transformed,10,10)
                    
            else:
                tkMessageBox.showinfo(message='Incorrect index!')
                self._index.set(0)
        except ValueError:
            pass