Ply und newlines
Verfasst: Freitag 26. Dezember 2008, 06:06
Hallo,
ich versuche gerade einen Compiler für ein paar Regeln zu schreiben. Der Syntax der Regeln sieht folgendermaßen an einem Beispiel erklärt aus:
Regel 'A' ist erfüllt, wenn Regel B oder C und 2 Regeln der Menge {D,E,F} erfüllt sind. Der Parser funktioniert soweit auch ganz gut, aber bei vorhandenen newlines bricht er mit einer Fehlermeldung ab. Wenn ich die 2. Zeile des obigen Beispiels mit # auskommentiere, dann klappt es mit dem Erkennen der 1. Regel.
Die Fehlermeldung lautet:
Muss ich newline in eine der Regeln mit aufnehmen (wahrscheinlich in p_rule_prereq) und dann eine leere Liste zurückgeben (habe ich auch schon versucht, aber hat zum gleichen Ergebnis geführt)?
Vielleicht weiß ja jemand Rat.
lunas
ich versuche gerade einen Compiler für ein paar Regeln zu schreiben. Der Syntax der Regeln sieht folgendermaßen an einem Beispiel erklärt aus:
Code: Alles auswählen
A = 1{B,C} & 2{D,E,F}
F = 1{G}
Code: Alles auswählen
import ply.lex as lex
import ply.yacc as yacc
import os
import sys
rules = """
A = 1{B,C} & 2{D,E,F}
F = 1{G}
"""
tokens = (
'NUMBER', 'NAME', 'OPEN_BRACE', 'CLOSE_BRACE', 'COMMA', 'AND', 'EQUALS', #'NEWLINE',
)
t_ignore = " \r\t+~[].|!?%@"
t_NUMBER = r'[0-9][0-9XxA-Fa-f]*'
t_NAME = r'[<>A-Za-z_][A-Za-z0-9_]*'
t_OPEN_BRACE = r'{'
t_CLOSE_BRACE = r'}'
t_COMMA = r','
t_AND = r'&'
t_EQUALS = r'='
def t_NEWLINE(t):
r'\n+'
t.lexer.lineno += len(t.value)
def t_comment(s):
r'\#.*'
def t_error(t):
raise TypeError("Unknown text '%s'" % (t.value,))
lex.lex()
class Rule(object):
def __init__(self, rule, prereq):
self.rule = rule
self.prereq = prereq
def __repr__(self):
return "Rule(%s, %s)" % (self.rule, self.prereq)
class Prereq(object):
def __init__(self, count, rule_list):
self.rule_list = rule_list
self.count = count
def __repr__(self):
return "Prereq(%s, %s)" % (self.count, self.rule_list)
def p_rule_prereq(p):
"""
rule_prereq :
rule_prereq : NAME EQUALS prereq_list
"""
if len(p) == 1 or len(p) == 2:
p[0] = []
else:
p[0] = Rule(p[1], p[3])
print'catch'
def p_prereq_list(p):
"""
prereq_list : prereq
prereq_list : prereq_list AND prereq
"""
if len(p) == 2:
p[0] = [p[1]]
elif len(p) == 4:
p[0] = p[1] + [p[3]]
def p_rule_list(p):
"""
rule_list : rule_list COMMA rule
rule_list : rule
"""
if len(p) == 4:
p[0] = p[1] + p[3]
elif len(p) == 2:
p[0] = p[1]
def p_prereq(p):
"prereq : NUMBER OPEN_BRACE rule_list CLOSE_BRACE"
p[0] = Prereq(p[1], p[3])
def p_rule(p):
"rule : NAME"
p[0] = [p[1]]
def p_error(p):
raise TypeError("unknown text at %r" % (p,))
yacc.yacc()
print yacc.parse(rules)
Code: Alles auswählen
yacc: Generating LALR parsing table...
Traceback (most recent call last):
File "rule.py", line 120, in <module>
print yacc.parse(rules)
File "build\bdist.win32\egg\ply\yacc.py", line 346, in parse
File "rule.py", line 115, in p_error
raise TypeError("unknown text at %r" % (p,))
TypeError: unknown text at LexToken(NAME,'F',3,23)
Vielleicht weiß ja jemand Rat.
lunas