2016-11-22 2 views
1

Ich versuche zu loggen Ausdruck mit 'impliziert' 'und' 'oder' und 'Negation' mit Klammern wie (Q(a)=>R(b)) mit PLY wo Q (a) und R (b) sind Prädikate und immer Beginnen Sie mit Blockbuchstaben und die Variablen "a" und "b" sind einzelne Kleinbuchstaben.Analysieren logischen Ausdruck mit PLY

Jeder Operator und seine Operanden werden von Klammern umgeben. Einige andere Beispiele für logische Ausdrücke, die ich zu analysieren versuche, sind ((D(q,w) & E(r,s)) => F(t)), (((G(a)=>H(b))=>I(c))=>J(d)), (~(~(~P(a)))).

Unten ist der Code i

import ply.lex as lex 
import ply.yacc as yacc 

tokens = [ 
    'LPAREN', 
    'RPAREN', 
    'PREDICATE', 
    'AND', 
    'OR', 
    'IMPLIES', 
    'NEGATION' 
] 

t_PREDICATE = r'[A-Z][a-z]*\(([A-Za-z,]+)\)' 
t_LPAREN = r'\(' 
t_RPAREN = r'\)' 
t_AND = r'\&' 
t_OR = r'\|' 
t_IMPLIES = r'\=>' 
t_NEGATION = r'\~' 

t_ignore = r' ' 

def t_error(t): 
    print("Illegeal characters") 
    t.lexer.skip(1) 

lexer = lex.lex() 


def p_expression_negation(p): 
    ''' 
    expression : LPAREN NEGATION PREDICATE RPAREN 

    ''' 
    p[0] = (p[2], p[3]) 
    print(p[0]) 

def p_expression_single(p): 
    ''' 
    expression : PREDICATE 
    ''' 
    p[0] = p[1] 
    print(p[0]) 

def p_expression(p): 
    ''' 
    expression : LPAREN term IMPLIES term RPAREN 
       | LPAREN term AND term RPAREN 
       | LPAREN term OR term RPAREN 
    ''' 

    p[0] = (p[3], p[2], p[4]) 
    print(p[0]) 

def p_term_negation(p): 
    ''' 
    term : LPAREN NEGATION PREDICATE RPAREN 

    ''' 
    p[0] = (p[2], p[3]) 
    return p[0] 


def p_term_single(p): 
    ''' 
    term : PREDICATE 
    ''' 
    p[0] = (p[1]) 
    return p[0] 

def p_term_multiple(p): 
    ''' 
    term : LPAREN PREDICATE IMPLIES PREDICATE RPAREN 
     | LPAREN PREDICATE AND PREDICATE RPAREN 
     | LPAREN PREDICATE OR PREDICATE RPAREN 

    ''' 
    p[0] = (p[3], p[2], p[4]) 
    return p[0] 


def p_error(p): 
    print("Syntax error in input!") 

parser = yacc.yacc() 

while True: 
    try: 
     s = input('Enter the input') 
    except EOFError: 
     break 
    parser.parse(s, lexer=lexer) 

Aber dieses Programm nicht für logischen Ausdruck wie (((G(a)=>H(b))=>I(c))=>J(d)), (~(~(~P(a)))), da diese Ausdrücke mit mehr als 2 ‚(‘ beginnen, ich nicht in der Lage geschrieben habe, bin meinen Code zu modifizieren, anzupassen solche Fälle, in denen Klammern am Anfang des Ausdrucks Öffnung können von 1 bis n reichen.

ich glaube, ich Rekursion verwenden sollte, sondern dass auch für mich versagt.

Dies ist mein erstes Programm mit PLY so nicht in der Lage Um eine richtige Grammatikregel für yacc zu schreiben, wäre es eine große Hilfe, wenn mir jemand helfen könnte.

Antwort

0

Ich weiß nicht, wo ich term verwenden soll, aber das funktioniert für mich.

EDIT:

vorherige Version war nicht ideal, weil Q(a)=>R(b) wurde als richtiger Ausdruck behandelt. Die aktuelle Version behandelt Q(a)=>R(b) als falschen Ausdruck.

import ply.lex as lex 
import ply.yacc as yacc 

tokens = [ 
    'LPAREN', 
    'RPAREN', 
    'PREDICATE', 
    'AND', 
    'OR', 
    'IMPLIES', 
    'NEGATION' 
] 

t_PREDICATE = r'[A-Z][a-z]*\(([A-Za-z,]+)\)' 
t_LPAREN = r'\(' 
t_RPAREN = r'\)' 
t_AND = r'\&' 
t_OR = r'\|' 
t_IMPLIES = r'\=>' 
t_NEGATION = r'\~' 

t_ignore = r' ' 

def t_error(t): 
    print("Illegeal characters") 
    t.lexer.skip(1) 

lexer = lex.lex() 


def p_expression_normal(p): 
    ''' 
    expression : LPAREN PREDICATE RPAREN 
    ''' 
    p[0] = ('()', p[2]) 
    print(p[0]) 

def p_expression_negation(p): 
    ''' 
    expression : LPAREN NEGATION PREDICATE RPAREN 
       | LPAREN NEGATION expression RPAREN 
    ''' 
    p[0] = ('()', p[2], p[3]) 
    print(p[0]) 

def p_expression_operation(p): 
    ''' 
    expression : LPAREN expression IMPLIES expression RPAREN 
       | LPAREN expression AND expression RPAREN 
       | LPAREN expression OR expression RPAREN 
       | LPAREN PREDICATE IMPLIES expression RPAREN 
       | LPAREN PREDICATE AND expression RPAREN 
       | LPAREN PREDICATE OR expression RPAREN 
       | LPAREN expression IMPLIES PREDICATE RPAREN 
       | LPAREN expression AND PREDICATE RPAREN 
       | LPAREN expression OR PREDICATE RPAREN 
       | LPAREN PREDICATE IMPLIES PREDICATE RPAREN 
       | LPAREN PREDICATE AND PREDICATE RPAREN 
       | LPAREN PREDICATE OR PREDICATE RPAREN    
    ''' 
    p[0] = ('()', p[3], p[2], p[4]) 
    print(p[0]) 

def p_error(p): 
    print("Syntax error in input!") 

parser = yacc.yacc() 


#while True: 
# try: 
#  s = input('Enter the input: ') 
# except EOFError: 
#  break 
# parser.parse(s, lexer=lexer) 

test = [ 
    '(Q(a))', # OK 
    'Q(a)', # wrong 
    '(Q(a)=>R(b))', # OK 
    'Q(a)=>R(b)', # wrong 
    '(((G(a)=>H(b))=>I(c))=>J(d))', # OK 
    '((G(a)=>H(b))=>I(c))=>J(d)', # wrong 
    '(~(~(~P(a))))', # OK 
    '~(~(~P(a)))', # wrong 
    '((D(q,w) & E(r,s)) => F(t))', # OK 
    '(D(q,w) & E(r,s)) => F(t)', # wrong 
] 

for s in test: 
    print(s) 
    print() 
    parser.parse(s, lexer=lexer) 
    print('\n------\n') 
+0

Ich habe eine neue Version. – furas

Verwandte Themen