Есть ли хороший, многоразовый синтаксический анализатор, который преобразует строку в иерархию списков?

StackOverflow https://stackoverflow.com/questions/456259

Вопрос

Я бы хотел взять строку, подобную этой:

[One, Two[A, B[i, ii, iii, iv], C], Three]

И преобразуйте его в иерархию списков, чтобы, если я выполню такой код, как следующий:

Console.Write(myList[1][1][2]);

Результатом будет:

iii

Я надеюсь, что это достаточно распространенное требование, чтобы существовал какой-нибудь простой код синтаксического анализа, написанный на C # this.

Дайте мне знать, если можно сформулировать мой вопрос более четко.

Это было полезно?

Решение

XML или JSON есть отличные методы для хранения подобных вещей.

Как сказал Спенс - это сложная проблема - я не рекомендую создавать свою собственную.

Прокрутите вниз до нижней части этой ссылки JSON, чтобы ознакомиться с реализациями на большинстве языков.

Другие советы

Мне пришлось бы использовать регулярное выражение.Совпадения подстрок и подвыражения могут дать вам рекурсию для получения подстроки...уровни внутри.

Используйте что-то вроде /^\[(.+)\]$/ в preg, чтобы собрать предметы одного уровня.Обрабатывайте это до тех пор, пока вы больше не будете получать уровень, взрывайтесь на "," после того, как наберетесь смелости для одной серии.

Разделите результат на ','.

должно получиться что-то вроде

  • [Один, Два[A, B[i, ii, iii, iv], C], Три]
    • Один
    • Два
    • [A, B[i, ii, iii, iv], C]
      • A
      • B
      • [i, ii, iii, iv]
        • i
        • ii
        • iii
        • iv
      • C
    • Три

Наконец, обрежьте левые / правые пробелы, чтобы получить отточенный результат.

Вам нужны массивы или списки?

Это было бы чрезвычайно сложно сделать со строками, поскольку вам приходится иметь дело с пробелами или использованием запятой в элементе и т.д.

Если у вас есть контроль над тем, что находится в этом списке, я предлагаю вам заглянуть в XML или двоичную сериализацию, в которых есть библиотеки, которые помогут вам сделать это.

Это непрактичный ответ, но если вы можете использовать бета-версию .NET 4.0, вы могли бы заглянуть в Oslo (и последующие инструменты), которые Microsoft разрабатывает для текстовых DSL, что, похоже, именно то, что вам нужно.

Я также голосую за XML, или JSON, или другой формат, если у вас есть возможность управлять этим форматом.Но из-за отсутствия этого, вот реализация синтаксического анализатора на Python, потому что мне было скучно.

class ExprParser(object):
current = []
list_stack = []

def __init__(self):
    pass

def parse(self,input):
    for atom in [s.strip() for s in input.split(',')]:
        self.parse_atom(atom)
    return self.current

def do_pushes(self,atom):
    """ Strip off the '[' and push new lists """
    i = 0
    while i < len(atom) and atom[i] == '[':
        self.push()
        i += 1
    return atom[i:]

def do_pops(self,atom):
    """ Pop the lists """
    i = 0
    while i < len(atom) and atom[i] == ']':
        self.pop()
        i += 1

def parse_atom(self,atom):
    push_start = atom.find('[')

    rest = self.do_pushes(atom[push_start:]) if push_start >= 0 else atom

    pop_start = rest.find(']')

    val = rest[:pop_start] if pop_start >= 0 else rest

    self.add(val)

    if pop_start >= 0:
        self.do_pops(rest[pop_start:])

def push(self):
    self.current = []
    self.list_stack.append(self.current)

def pop(self):
    done = self.list_stack.pop()
    self.current = self.list_stack[-1] if self.list_stack else done
    if self.current is not done:
        self.add(done)

def add(self,val):
    self.current.append(val)

Используйте, как:

parser = ExprParser()
parser.parse('[One, Two[A, B[i, ii, iii, iv], C], Three]')

Однако обработка ошибок при неправильном вводе отсутствует.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top