简体   繁体   English

在布尔表达式中添加隐式括号的算法

[英]Algorithm to add implied parentheses in boolean expression

I have a string such as "A and B or not C and D". 我有一个字符串,例如“ A和B或不是C和D”。 The atoms are all simple uppercase letters A,B,C... and the operators are only { and, or, not }. 原子都是简单的大写字母A,B,C ...,并且运算符只是{和,或不是}。 I would like to devise an algorithm that can add parentheses that are implied by the usual rules of precedence. 我想设计一种算法,可以添加通常的优先级规则所隐含的括号。

Can anyone think of a very simple way to do this? 谁能想到一个非常简单的方法来做到这一点? perhaps using Regex? 也许使用正则表达式?

The desired output is "(A and B) or ((not C) and D)". 所需的输出是“(A和B)或((非C)和D)”。

It can be as simple as this (Python code ahead): 可以这样简单(前面的Python代码):

def popnext(stream, token):
    if stream[0:len(token)] == list(token):
        del stream[0:len(token)]
        return True
    return False

def parse_binary(stream, operator, nextfn):
    es = [nextfn(stream)]
    while popnext(stream, operator):
        es.append(nextfn(stream))
    return '(' + ' {} '.format(operator).join(es) + ')' if len(es) > 1 else es[0]

def parse_ors(stream):
    return parse_binary(stream, 'or', parse_ands)

def parse_ands(stream):
    return parse_binary(stream, 'and', parse_unary)

def parse_unary(stream):
    if popnext(stream, 'not'):
        return '(not {})'.format(parse_unary(stream))
    return parse_primary(stream)

def parse_primary(stream):
    if popnext(stream, '('):
        e = parse_ors(stream)
        popnext(stream, ')')
        return e
    return stream.pop(0)


def evaluate(expression):
    return parse_ors(list(expression.replace(' ', '')))[1:-1]

print evaluate('A and B or not C and D')
print evaluate('A and (B or not C) and D')

result: 结果:

(A and B) or ((not C) and D)
A and (B or (not C)) and D

A grammar for your these Strings might be defined by the following production rules : 这些字符串的语法可以由以下生产规则定义:

  1. S → E S→E
  2. E → E or E E→E or E
  3. E → F E→F
  4. F → F and F F→F and F
  5. F → T F→T
  6. F → not T F→ not T
  7. T → A T→ A
  8. T → B T→ B
  9. T → C T→ C
  10. T → D T→ D

(Make rule 6 " T → not T"), if strings like "not not D and not not not B" shall be allowed, too.) (使规则6为“ T →not T”),如果也应允许类似"not not D and not not not B"字符串。)

While this grammar is context free, it isn't regular . 尽管该语法是上下文无关的,但它不是常规的 I don't think a regular grammar for your strings exists, so regular expressions are not sufficient to match exactly these strings, and by extension also not to parse and transform (re-write) them correctly. 我认为您的字符串不存在常规语法,因此正则表达式不足以精确匹配这些字符串,并且通过扩展,也无法正确解析和转换(重写)它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM