Напротив View.bringToFront () в Android

Мне было интересно, существует ли какой-то противоположный метод View.bringToFront () ? Устаревший синтаксический анализатор был основан на регулярных выражениях и был полным кошмаром для обслуживания, поэтому я придумал свое собственное решение, основанное на ...

У меня есть язык разметки, который похож на разметку и тот, который используется SO.

Устаревший синтаксический анализатор основывался на регулярных выражениях и был полным кошмаром для обслуживания, поэтому я придумал собственное решение, основанное на грамматике EBNF и реализованное с помощью mxTextTools / SimpleParse.

Однако существуют проблемы с некоторыми токенами, которые могут включать друг друга и я не вижу «правильного» способа сделать это.

Вот часть моей грамматики:

newline          := "\r\n"/"\n"/"\r"
indent           := ("\r\n"/"\n"/"\r"), [ \t]
number           := [0-9]+
whitespace       := [ \t]+
symbol_mark      := [*_>#`%]
symbol_mark_noa  := [_>#`%]
symbol_mark_nou  := [*>#`%]
symbol_mark_nop  := [*_>#`]
punctuation      := [\(\)\,\.\!\?]
noaccent_code    := -(newline / '`')+
accent_code      := -(newline / '``')+
symbol           := -(whitespace / newline)
text             := -newline+
safe_text        := -(newline / whitespace / [*_>#`] / '%%' / punctuation)+/whitespace
link             := 'http' / 'ftp', 's'?, '://', (-[ \t\r\n<>`^'"*\,\.\!\?]/([,\.\?],?-[ \t\r\n<>`^'"*]))+
strikedout       := -[ \t\r\n*_>#`^]+
ctrlw            := '^W'+
ctrlh            := '^H'+
strikeout        := (strikedout, (whitespace, strikedout)*, ctrlw) / (strikedout, ctrlh)
strong           := ('**', (inline_nostrong/symbol), (inline_safe_nostrong/symbol_mark_noa)* , '**') / ('__' , (inline_nostrong/symbol), (inline_safe_nostrong/symbol_mark_nou)*, '__')
emphasis              := ('*',?-'*', (inline_noast/symbol), (inline_safe_noast/symbol_mark_noa)*, '*') / ('_',?-'_', (inline_nound/symbol), (inline_safe_nound/symbol_mark_nou)*, '_')
inline_code           := ('`' , noaccent_code , '`') / ('``' , accent_code , '``')
inline_spoiler        := ('%%', (inline_nospoiler/symbol), (inline_safe_nop/symbol_mark_nop)*, '%%')
inline                := (inline_code / inline_spoiler / strikeout / strong / emphasis / link)
inline_nostrong       := (?-('**'/'__'),(inline_code / reference / signature / inline_spoiler / strikeout / emphasis / link))
inline_nospoiler       := (?-'%%',(inline_code / emphasis / strikeout / emphasis / link))
inline_noast          := (?-'*',(inline_code / inline_spoiler / strikeout / strong / link))
inline_nound          := (?-'_',(inline_code / inline_spoiler / strikeout / strong / link))
inline_safe           := (inline_code / inline_spoiler / strikeout / strong / emphasis / link / safe_text / punctuation)+
inline_safe_nostrong  := (?-('**'/'__'),(inline_code / inline_spoiler / strikeout / emphasis / link / safe_text / punctuation))+
inline_safe_noast     := (?-'*',(inline_code / inline_spoiler / strikeout / strong / link / safe_text / punctuation))+
inline_safe_nound     := (?-'_',(inline_code / inline_spoiler / strikeout / strong / link / safe_text / punctuation))+
inline_safe_nop        := (?-'%%',(inline_code / emphasis / strikeout / strong / link / safe_text / punctuation))+
inline_full           := (inline_code / inline_spoiler / strikeout / strong / emphasis / link / safe_text / punctuation / symbol_mark / text)+
line                  := newline, ?-[ \t], inline_full?
sub_cite              := whitespace?, ?-reference, '>'
cite                  := newline, whitespace?, '>', sub_cite*, inline_full?
code                  := newline, [ \t], [ \t], [ \t], [ \t], text
block_cite            := cite+
block_code            := code+
all                   := (block_cite / block_code / line / code)+

Первая проблема - спойлер, сильный и акцент могут включать друг друга в произвольном порядке. И возможно, что позже мне понадобятся дополнительные встроенные разметки.

Мое текущее решение заключается в создании отдельного токена для каждой комбинации (inline_noast, inline_nostrong и т. Д.), но очевидно, что число таких комбинаций растет слишком быстро с ростом количества элементов разметки.

Вторая проблема заключается в том, что эти упреждающие заголовки с сильным / упорным поведением ОЧЕНЬ плохо работают в некоторых случаях плохой разметки, например __._.__ * __ .__...___._.____.__ ** ___ *** (множество случайно расположенных символов разметки). Для анализа нескольких килобайт такого произвольного текста требуются минуты.

Что-то не так с моей грамматикой, или мне следует использовать какой-то другой вид синтаксического анализатора для этой задачи?

8
задан Daniel Kluev 21 August 2010 в 00:13
поделиться

1 ответ

Если одна вещь включает другую, то обычно вы обрабатываете их как отдельные токены, а затем вкладываете их в грамматику. Lepl ( http://www.acooke.org/lepl , который я написал) и PyParsing (который, вероятно, является самым популярным синтаксическим анализатором на чистом Python) позволяют вам рекурсивно вкладывать вещи.

Итак, в Лепле вы можете написать примерно такой код:

# these are tokens (defined as regexps)
stg_marker = Token(r'\*\*')
emp_marker = Token(r'\*') # tokens are longest match, so strong is preferred if possible
spo_marker = Token(r'%%')
....
# grammar rules combine tokens
contents = Delayed() # this will be defined later and lets us recurse
strong = stg_marker + contents + stg_marker
emphasis = emp_marker + contents + emp_marker
spoiler = spo_marker + contents + spo_marker
other_stuff = .....
contents += strong | emphasis | spoiler | other_stuff # this defines contents recursively

Тогда вы увидите, я надеюсь, как содержимое будет соответствовать вложенному использованию сильного, акцентного и т. Д.

Для финальной версии нужно сделать гораздо больше. решение, и эффективность может быть проблемой в любом синтаксическом анализаторе на чистом Python (есть некоторые синтаксические анализаторы, реализованные на C, но вызываемые из Python. Они будут быстрее, но могут быть сложнее в использовании; я не могу рекомендовать их, потому что у меня нет не использовал их).

6
ответ дан 5 December 2019 в 22:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: