LINUX.ORG.RU

синтаксический разбор

 , синтаксический анализатор


0

4

есть задача:

дан текст <div>level 0<div>level 1<div>level 2</div></div>level 0</div>

нужно на выходе получить:

level 0
    level 1
        level 2
level 0
то есть в зависимости от вложенности нужно добавить 4 пробела перед подстрокой, заключенной в <div></div>

нужно построить дерево, что на эту тему почитать сравнительно простого, чтобы за вечер се понять?

или граф, как проще сделать?

★★★

Последнее исправление: IvanR (всего исправлений: 1)

Используй любую xml библиотеку. Если хочешь сам писать, то самое простое - «рекурсивный спуск».

Aswed ★★★★★
()

Нахрена тебе тут дерево?
Сделай int, на каждый открытый тег делай +1, на каждый закрытый -1.
Умножай этот int на 4 пробела и пиши перед следующим

anonymous
()
Ответ на: комментарий от Aswed

Если хочешь сам писать, то самое простое - «рекурсивный спуск».

Самое простое (в данном случае) - конечный автомат с магазинной памятью

yoghurt ★★★★★
()
Ответ на: комментарий от pon4ik

не, не опечатка, такой синтаксис, в общем это лаба.

IvanR ★★★
() автор топика
Ответ на: комментарий от anonymous

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

IvanR ★★★
() автор топика

sed

$ echo " <div>level 0<div>level 1<div>level 2</div></div>level 0</div>" |\
sed 's/<div>/←\n/g;s~</div>~→\n~g;s/[^←→]\+/&\n/g'|\
sed -rn '/^\s*$/b;/←/{x;s/^/    /;x;b};/→/{x;s/    //;x;b};H;g;s/\n.*//;x;s/\n//;p'
    level 0
        level 1
            level 2
    level 0
emulek
()
Ответ на: комментарий от pon4ik

Не хватает блока <div>

нет, всё правильно: 3 открывающих и 3 закрывающих.

Только почему-то у ТСа уровень «1» называется «level 0».

emulek
()
Ответ на: комментарий от yoghurt

Самое простое (в данном случае) - конечный автомат с магазинной памятью

нет. В данном случае нам нужно знать _только_ _уровень_ вложенности. И теги тут везде одинаковые. Вот если-бы <table><tr><td>… тогда да, нужен-бы был стек, и реализация на sed обладала-бы высоким уровнем упоротости(но была-бы всё равно возможна, из-за тьюринг-полноты sed).

emulek
()
Ответ на: комментарий от emulek

Да, с магазинной слишком, тут просто счетчик.

<table><tr><td>

Тут, кстати, тоже, для индентации достаточно, для валидации - уже нет

yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt

Тут, кстати, тоже, для индентации достаточно

обычно нужно уметь вылавливать такое <tr><td></tr></td>, т.е. валидация становится необходимой. Ну а с одним тегом нет в этом особой нужды, т.к. обычно лишний тег тупо игнорируется. Что делать с вышеприведённым фрагментом — непонятно.

emulek
()
Ответ на: комментарий от IvanR

а еще есть шахматы на sed

ЩИТО?

и кажется тетрис :)

тетрис действительно есть, проверял, работает. ИЧСХ, написан самкой рода Homo sapiens sapiens (кроме всякой фигни она какие-то коммиты в ядро посылала, но их я не смотрел).

Такой вызов к зазнавшимся программистам-с-пенисом: а вам слабо? Мне — слабо, терпения не хватит.

emulek
()
Ответ на: комментарий от IvanR

а, сравнительно недавно. Потому я и не в курсе.

Русские как обычно отстаивают сомнительную честь делать самые бесполезные вещи; как сказал наш Поэт: «Только нам и славы, что кованные блохи» ©СашБаш.

PS: вот ещё ссылка Шахматы, или «Как правильно почесать руки» которая прошла мима меня, т.к. я в Games/ не заглядываю.

emulek
()
Последнее исправление: emulek (всего исправлений: 1)
Ответ на: комментарий от emulek

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

IvanR ★★★
() автор топика
Ответ на: комментарий от IvanR

наверно на sed никогда ничего более сложного в истории человечества не напишут

на самом деле там нет ничего архисложного. C/C++ сложнее. Если ты попробуешь писать сложные программы на sed/brainfuck'е, то заметишь, что сложно только в начале. Потом это нудно и долго. Ну как вилкой копать траншею. Sed это и есть такая «вилка», а C и особенно C++ — экскаватор. Экскаватором _сложнее_ и не каждый сможет (во всяком случае без многомесячного обучения). Но быстрее, один раз копнёшь, и метр траншеи готов. Вилкой весь день копать, но за то справится любой идиот без обучения(ну пару ударов плетью и пару пряников не в счёт).

emulek
()

Кривое решение на Swi-Prolog:

nodes([Node]) --> node(Node).
nodes([Node|Rest]) --> node(Node), nodes(Rest).
node(Node) --> div(Node) ; text(Node).

div(div(Children)) --> div_start, nodes(Children), div_end.
text(text(Text)) --> \+ nondet, [Char], text(text(Rest)), { Text = [Char|Rest] }.
text(text(Text)) --> \+ nondet, [Char], { Text = [Char] }.

div_start --> "<div>".
div_end --> "</div>".
nondet --> div_start ; div_end.

print(Nodes) :- print(Nodes, 0).
print(Nodes, Level) :-
    forall(member(Node, Nodes), (
        Node = div(Children) -> NewLevel is Level + 1, print(Children, NewLevel) ;
        Node = text(Text) -> tab(Level), format('~s~n', [Text])
    )).

tab(0).
tab(X) :- Y is X - 1, format('~w', '    '), tab(Y).

run_program :-
    Input = "<div>level0<div>level1<div>level2</div></div>level0</div>",
    phrase(nodes(Nodes), Input),
    print(Nodes).

Output:

?- run_program.

    level0
        level1
            level2
    level0

runtime ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.