2016-03-29 12 views
0

Ich versuche eine Struktur in meiner Grammatik (in PLY) zu implementieren. Der Parser erzeugt keine Syntaxfehler, wenn ich meine Struktur in eine Zeile schreibe, aber wenn ich sie in mehrere Zeilen schreibe, erzeugt sie Syntaxfehler in den Zeilen, die geschweifte Klammern enthalten. Mein Code (ohne ast.py, weil ich nicht denke, es ist hilfreich) folgt:Ignorieren neuer Zeilenzeichen in PLY/Yacc Productions

main.py

from parser import * 
import ply.yacc as yacc 
yacc.yacc() 

def main(): 
    with open('main.smp') as fp: 
     for line in fp: 
      try: 
       yacc.parse(line) 
      except EOFError: 
       break   

main() 

parser.py (enthält lexing Code als auch)

import sys 
sys.path.insert(0,"../..") 

from ast import * 

tokens = (
    'NAME', 'NUMBER', 'STRUCT', 'LBRACE', 'RBRACE' 
    ) 

literals = ['=','+','-','*','/', '(',')', '{', '}'] 

# Tokens 
t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*' 
t_LBRACE = r'\{' 
t_RBRACE = r'\}' 

def t_NUMBER(t): 
    r'\d+' 
    try: 
     t.value = int(t.value) 
    except ValueError: 
     print "Integer value too large", t.value 
     t.value = 0 
    return t 

def t_STRUCT(t): 
    r'struct ' 
    return t 

t_ignore = " \t" 

def t_newline(t): 
    r'\n+' 
    t.lexer.lineno += len(t.value) 
    print "new line" 

def t_error(t): 
    print "Illegal character '%s'" % t.value[0] 
    t.lexer.skip(1) 

# Build the lexer 
import ply.lex as lex 
lexer = lex.lex() 

lexer.brace_count = 0 

# Parsing rules 
precedence = (
    ('left','+','-'), 
    ('left','*','/'), 
    ('right','UMINUS'), 
    ) 

start='statement' 

def p_statement_assign(p): 
    'statement : NAME "=" expression' 

    names[p[1]] = p[3] 

def p_statement_struct(p): 
    "statement : STRUCT NAME LBRACE statement RBRACE" 
    print "parsed struct" 

def p_statement_expr(p): 
    'statement : expression' 

    try: 
     print p[1].codegen() 
    except AttributeError: 
     print p[1], "no attribute" 

def p_expression_binop(p): 
    '''expression : expression '+' expression 
        | expression '-' expression 
        | expression '*' expression 
        | expression '/' expression''' 

    p[0] = BinOpNode(p[1], p[3], p[2]) 

def p_expression_uminus(p): 
    "expression : '-' expression %prec UMINUS" 

    p[0] = NumNode(-p[2]) 

def p_expression_group(p): 
    "expression : '(' expression ')'" 

    p[0] = NumNode(p[2]) 

def p_expression_number(p): 
    "expression : NUMBER" 

    p[0] = NumNode(p[1]) 

def p_expression_name(p): 
    "expression : NAME" 

    try: 
     p[0] = names[p[1]] 
    except LookupError: 
     print "Undefined name '%s'" % p[1] 
     p[0] = 0 

def p_error(p): 
    try: 
     print "{1}: Syntax error on '{0}'".format(p.value, lexer.lineno) 
    except AttributeError: 
     print "{0}: Syntax error on line".format(lexer.lineno) 

Haupt .smp

struct test 
{ 
    9+9 
} 

Ausgang

new line 
2: Syntax error on line 
2: Syntax error on '{' 
new line 
new line 
18 
4: Syntax error on '}' 
+0

Ich denke, dass die Aktion für 'p_expression_uminus 'falsch ist, da' p [2] 'in diesem Fall ein AST-Knoten sein könnte (z. B. wenn der Ausdruck' - (a + b) 'ist). Aber das ist für deine Frage nicht relevant. – rici

+0

Danke das kann korrekt sein und ich werde das untersuchen. –

Antwort

1

Ihre Hauptschleife:

def main(): 
    with open('main.smp') as fp: 
     for line in fp: 
      try: 
       yacc.parse(line) 
      except EOFError: 
       break 

bewusst ist jede Eingangsleitung separat Parsen. Jede Zeile müsste also eine vollständige statement sein, damit die Syntaxanalyse erfolgreich ist (für diese Zeile).

+0

In der Tat scheint das das Problem zu sein. Ich habe stattdessen die gesamte Zeichenfolge analysiert, aber jetzt bekomme ich nur in der letzten Zeile einen Syntaxfehler, das '}'. Ich werde das weiter untersuchen und versuchen herauszufinden, ob das zusammenhängt. –

+0

Nachdem es die Festsetzung der gesamten Datei anstatt Zeile für Zeile zu analysieren bekomme ich diese Fehler: ** struct test {\ n 9 \ n } ** '1: Syntaxfehler auf '}'' * * struct test {9} ** '1: Syntaxfehler bei '{'' –

+0

@BennetLeff: Das könnte daran liegen, dass das Setzen von '{' und '} 'als Literale und als Muster den Scannergenerator verwirrt. Ich würde sie einfach zu Literalen machen und sie in der Grammatik mit einer literalen Syntax (wie '=') bezeichnen, da das einfacher und lesbarer ist. – rici