user765443
user765443

Reputation: 1892

Parenthesis matching code in python

I have written following code and it was working fine.But One of the case it is failing.I tried but not able to fix this issue.

#!/usr/bin/env py
import itertools
import sys
import sympy
import re
import pprint
def extract_next_state(s):
    p = re.compile('(\()|(\))')
    depth = 0
    startindex = None
    start_point = False
    for m in p.finditer(s):
        if m.group(1):          # (
            depth += 1
            print "depth (", depth
            if not start_point:
                startindex = m.start()
                start_point = True
        elif m.group(2):          # )
            depth -= 1
            print "depth )", depth
            if depth == 0:
                return s[startindex:m.end()]
    return s[startindex:] + ')' * depth

if __name__ == "__main__":
    #data = ['next_state=(~SE&((~B2&D)|(B2&lq))|(SE&SI))']
    #data = ['next_state=((~SE&((A1&A2)|(B1&B2)))|(SE&SI)))']
    #data = ['next_state=((((~SE&((A1&A2)|(B1&B2)))|(SE&SI)))']
    data = ['next_state=(D1&S&!SE)|(!S&(!SE&D0))|(SE&SI))']
    data_1 = data[0].split(',')
    com = None
    for item in data_1:
        if item.find('next_state=')!= -1:
            item_list = item.split('=')
            item_op = extract_next_state(item_list[1])
            print item_op

output:

(D1&S&!SE)

Expected :

(D1&S&!SE)|(!S&(!SE&D0))|(SE&SI)

Upvotes: 0

Views: 166

Answers (1)

Adaephon
Adaephon

Reputation: 18329

You checking for depth == 0 as condition for returning from extract_next_state(). That is extract_next_state() returns once the matching closing parenthesis to the first opening parenthesis is found. The rest of the string is then not checked for any further parenthesis of course.

It's hard to recommend a solution without knowing what rules for "next_state" or the grammar for allowd expressions. But from the last line extract_next_state it seems you wish to close any open parenthesis. So a possible solution may be:

def extract_next_state(s):
    p = re.compile('(\()|(\))')
    depth = 0
    startindex = None
    endindex = None
    for m in p.finditer(s):
        if m.group(1):          # (
            depth += 1
            print "depth (", depth
            if not startindex:
                startindex = m.start()
        elif m.group(2):          # )
            depth -= 1
            print "depth )", depth
            if depth == 0:
                endindex = m.end()
    return s[startindex:(endindex if depth == 0 else None)] + ')' * depth

If with the last closing parenthesis all pairs are matched, the rest of the string is discarded, else a matching number of closing parentheses will be added.

Upvotes: 2

Related Questions