Yet Another Pain in the Po: Yapps2

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Clython
User
Beiträge: 151
Registriert: Samstag 21. August 2004, 13:58
Wohnort: Schweiz, BE-2500

Hallo Leute

ich bin gerade daran Yapps zu benutzen, um eine Grammatik für TIGERSearch Suchanfragen zu schreiben. Meine Grammatik sieht so aus:

Code: Alles auswählen

parser TIGERSearch:
    ignore:         "[ \r\t\n]+"
    token CON:      "&"
    token VAR:      "#[a-zA-Z0-9]+?:"
    token NODE:     "\[.*?\][$ ]"
    token PRED:     "[a-z]\([0-9,]+?\)"
    token DOM:      "([<>\$]$|[!<>$][<>A-Za-z\*\$0-9,@\.~!]+?$)"
    token PREC:     "([\.]$|[\.!][\*0-9,\.]+?$)"
    token END:      "\*end\*"
    rule node:      NODE    {{ print NODE }}
    rule pred:      PRED    {{ print PRED }}
    rule dom:       DOM     {{ print DOM }}
    rule prec:      PREC    {{ print PREC }}
    rule varnode:   VAR     {{ print VAR }}
                    NODE    {{ print NODE }}
    rule loop:     (pred | dom | prec | node | varnode)
         | (pred | dom | prec | node | varnode) CON query
    rule query: loop END    {{ return True }}
Beim generieren des Codes, kriege ich folgende Meldung:

Code: Alles auswählen

Input Grammar: parser.g
Output File: parser.py
Warning: ( ( <pred> | <dom> | <prec> | <node> | <varnode> ) | ( ( <pred> | <dom> | <prec> | <node> | <varnode> ) CON <query> ) )
 * These tokens are being ignored: PRED, PREC, VAR
   due to previous choices using them.
Der mit Yapps generiert Code plus ein paar manuelle Änderungen sieht so aus:

Code: Alles auswählen

from string import *
import re
from yappsrt import *

class TIGERSearchScanner(Scanner):
    patterns = [
        ('[ \r\t\n]+', re.compile('[ \r\t\n]+')),
        ('CON', re.compile('&')),
        ('VAR', re.compile('#[a-zA-Z0-9]+?:')),
        ('NODE', re.compile('\[.*?\][$ ]')),
        ('PRED', re.compile('[a-z]\([0-9,]+?\)')),
        ('DOM', re.compile('([<>\$]$|[!<>$][<>A-Za-z\*\$0-9,@\.~!]+?$)')),
        ('PREC', re.compile('([\.]$|[\.!][\*0-9,\.]+?$)')),
        ('END', re.compile('\*end\*')),
    ]
    def __init__(self, string):
        string = string.replace("&", " & ")
        string = string + " *end*"
        Scanner.__init__(self,None,['[ \r\t\n]+'],string)

class TIGERSearch(Parser):
    def node(self):
        NODE = self._scan('NODE')
        print NODE

    def pred(self):
        PRED = self._scan('PRED')
        print PRED

    def dom(self):
        DOM = self._scan('DOM')
        print DOM

    def prec(self):
        PREC = self._scan('PREC')
        print PREC

    def varnode(self):
        VAR = self._scan('VAR')
        print VAR
        NODE = self._scan('NODE')
        print NODE

    def loop(self):
        _token_ = self._peek('PRED', 'DOM', 'PREC', 'NODE', 'VAR')
        _token_ = self._peek('PRED', 'DOM', 'PREC', 'NODE', 'VAR')
        if _token_ == 'PRED':
            pred = self.pred()
        elif _token_ == 'DOM':
            dom = self.dom()
        elif _token_ == 'PREC':
            prec = self.prec()
        elif _token_ == 'NODE':
            node = self.node()
        elif _token_ == 'VAR':
            varnode = self.varnode()
        else:# in ['DOM', 'NODE']
            _token_ = self._peek('PRED', 'DOM', 'PREC', 'NODE', 'VAR')
            if _token_ == 'PRED':
                pred = self.pred()
            elif _token_ == 'DOM':
                dom = self.dom()
            elif _token_ == 'PREC':
                prec = self.prec()
            elif _token_ == 'NODE':
                node = self.node()
            else:# == 'VAR'
                varnode = self.varnode()
            CON = self._scan('CON')
            query = self.query()

    def query(self):
        loop = self.loop()
        END = self._scan('END')


def parse(rule, text):
    P = TIGERSearch(TIGERSearchScanner(text))
    return wrap_error_reporter(P, rule)

if __name__ == '__main__':
    from sys import argv, stdin
    parse("query", "[cat=/[iI]ch/] & [cat='NP']")
Wenn ich den Code jetzt ausführe, kriege ich folgende Fehlermeldung:


Code: Alles auswählen

[cat=/[iI]ch/]
Trying to find one of END on line 1:
>  [cat=/[iI]ch/]  &  [cat='NP'] *end*
>                  ^
List of nearby tokens:
  (@0)  NODE  =  '[cat=/[iI]ch/] '
Traceback (most recent call last):
  File "parsert.py", line 83, in ?
    parse("query", "[cat=/[iI]ch/] & [cat='NP']")
  File "parsert.py", line 79, in parse
    return wrap_error_reporter(P, rule)
  File "yappsrt.py", line 173, in wrap_error_reporter
    return return_value
UnboundLocalError: local variable 'return_value' referenced before assignment
Ich raff nicht, warum das Teil nicht funktioniert? Meiner Meinung nach müsste die Grammatik sauber funktionieren. Kennt sich damit jemand aus, der mir einen Hinweis geben könnte? Vielen Dank!

Gruss aus Schweden

Clython
BlackJack

Ich weiss nicht ob es an der Warnung liegt, aber der solltest Du auf jeden Fall mal nachgehen. `yapps2` erzeugt einen LL(1) Parser, das heisst es wird nur ein Token im voraus angeschaut, um zu entscheiden welche Regel/Alternative angewendet werden soll und wenn ein PRED erkannt wurde, dann gibt es bei `loop` zwei Alternativen die mit PRED anfangen.
Antworten