2016-11-22 70 views
1

我试图使用PLY解析包含'隐含''和''或'和'否定'的逻辑表达式,其中括号为(Q(a)=>R(b)),其中Q(a)和R(b)是谓词并且始终从块字母开始,变量'a'和'b'将是单个小字母字符。使用PLY分析逻辑表达式

每个运算符及其操作数将被括号包围。我试图解析的逻辑表达式的其他例子是((D(q,w) & E(r,s)) => F(t)), (((G(a)=>H(b))=>I(c))=>J(d)), (~(~(~P(a))))

下面是我写

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) 

的代码,但逻辑表达这一计划失败,如(((G(a)=>H(b))=>I(c))=>J(d)), (~(~(~P(a))))因为这些表情开始超过2“(”,我不能够改变我的代码,以适应这种情况下,在表达的开始打开括号的范围可以从1到n。

我想我应该用递归但也失败了我。

这是我与PLY第一程序,所以不能为yacc写一个适当的语法规则,如果有人能帮助我,这将是非常有帮助的

回答

0

我不记得在哪里使用term但这对我很有用。

编辑:

一个版本是不理想的,因为Q(a)=>R(b)被视为正确的表达。

当前版本将Q(a)=>R(b)视为不正确的表达式。

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

我把新版本。 – furas