1

Тема: признавайтесь хто майстер лексерів та регулярок

признавайтесь хто майстер регулярок та працював з лексерами?

уже декілька днів пробую написати лексера для побудови ast щоб перетворювати bbcodes -> html

користуюсь leex, erlang
зажовується частина тегів, точніше - смайлики

на скільки я розумію - проблема в жадності регулярок

Прихований текст
зміна

[^\[]+

на

[^\[]+?

нічого не принесла

код і "кривий результат" --
https://gist.github.com/221V/ddc9ba7175 … 7b095a6c15

підкажіть будь-ласка де я туплю і як цей код виправити?
регулярки ніколи не були моєю сильною стороною)

дякую

https://blog.clever-games.win/
Це ще не кінець. Це навіть не початок кінця. Але, можливо, це кінець початку.
Зростання мудрості можна точно вимірювати ступенем зменшення злоби.

2 Востаннє редагувалося 221VOLT (09.01.2018 19:52:31)

Re: признавайтесь хто майстер лексерів та регулярок

мені відповіли таке

Robert Virding
Creator of Erlang

When multiple rules match leex is defined to return the longest matching pattern. If there is more than one pattern with the same length it will return the first one. This is the same as in lex, on which leex is based.

і ще таке

In your definitions you have

%L = [A-za-zА-Яа-я0-9.]

which is a very loose regex. When leex processes your text it looks for the longest match as Robert indicated. It turns out that this regex will match the entire string you submitted since the rule

%{L}+ : {token, {any_text, TokenLen, TokenChars}}.

will match the entire string. As the longest match it will return that. You can test it in iex with:

iex(1)> r = ~r/[A-za-zА-Яа-я0-9.]+/
~r/[A-za-zА-Яа-я0-9.]+/
iex(2)> Regex.match? r, "test:ninja::Otest:alien:"
true

Test against your regex's you'll see that

[^\[]+

also matches the entire string.

If I can make a suggestion - separate tokenising (leex) from parsing (yecc), You are trying to do too much I think, which makes it more complicated.

A simple (but incomplete) tokeniser which can process your test string follows. T

Definitions.

Tag        = [a-z]
OpenTag    = \[
CloseTag   = \]
Emoticon   = :

Rules.

:\)      : {token, {smile, 1}}.
8-\)     : {token, {smile, 4}}.
:'\( : {token, {smile, 5}}.
:ermm:   : {token, {smile, 6}}.
:D       : {token, {smile, 7}}.
<3    : {token, {smile, 8}}.
:\(      : {token, {smile, 9}}.
:O       : {token, {smile, 10}}.
:P       : {token, {smile, 11}}.
;\)      : {token, {smile, 12}}.

{OpenTag} : {token, {open_tag, TokenLine, TokenChars}}.
{Tag}+ : {token, {tag, TokenLine, TokenChars}}.
{CloseTag} : {token, {close_tag, TokenLine, TokenChars}}.
{Emoticon}{Tag}+{Emoticon} : {token, {emoticon, TokenLine, TokenChars}}.

Erlang code.

Robert Virding
Creator of Erlang

Note one thing: the regular expressions in leex and Regex are not the same. Regex supports the full perl regexs, it implemented internal in :re module which uses the PCRE library, while leex only allows a more limited set. A major benefit of the leex regexs, which are the same as in lex, is that they never need to backtrack which the perl ones do. With PCRE you can easily define a simple regex which will take a long long time to match, for example check here The :re module gets around this by putting a limit on how long the match is allowed to take before giving up.

------

допоможіть роздуплитися? *SCRATCH*

https://blog.clever-games.win/
Це ще не кінець. Це навіть не початок кінця. Але, можливо, це кінець початку.
Зростання мудрості можна точно вимірювати ступенем зменшення злоби.

3 Востаннє редагувалося Altair8800 (09.01.2018 15:02:45)

Re: признавайтесь хто майстер лексерів та регулярок

221VOLT написав:

уже декілька днів пробую написати лексера для побудови ast щоб перетворювати bbcodes -> html

Не знаю що таке лексери і з ерглантом не знайомий, але раз ви намагаєтесь замінити [] на <>, то на джаваскрипті це буде так:

str.replace(/\[/g/, '<');

Що у вас:

[^\[]+?

^ - може позначати початок рядка або всі крім наступного символу ( [^a] - будь-який символ, крім "а"). У вашій регулярці це другий випадок, тому виносьте ^ за квадратні дужки, якщо він позначає початок рядку.
Ще спробуйте помістити регулярку в круглі дужки (), бо зазвичай шукає тільки те, що в дужках.

4

Re: признавайтесь хто майстер лексерів та регулярок

Якщо не впевнені в регулярках, перевіряйте себе на онлайн-сервісах, таких як цей https://regexr.com/

5

Re: признавайтесь хто майстер лексерів та регулярок

Altair8800 написав:
str.replace(/\[/g/, '<');

І привіт експлойти в коментах. І добре, якщо усе завершиться безневинним дефейсом.
Якщо уже робити bb-коди, то робити стійкий до кулхацкерів парсинг.

Подякували: 0xDADA11C7, cheappi386, /KIT\, 221VOLT, leofun015

6 Востаннє редагувалося 221VOLT (09.01.2018 19:30:11)

Re: признавайтесь хто майстер лексерів та регулярок

Altair8800 написав:
221VOLT написав:

уже декілька днів пробую написати лексера для побудови ast щоб перетворювати bbcodes -> html

Не знаю що таке лексери і з ерглантом не знайомий, але раз ви намагаєтесь замінити [] на <>, то на джаваскрипті це буде так:

str.replace(/\[/g/, '<');

Що у вас:

[^\[]+?

^ - може позначати початок рядка або всі крім наступного символу ( [^a] - будь-який символ, крім "а"). У вашій регулярці це другий випадок, тому виносьте ^ за квадратні дужки, якщо він позначає початок рядку.
Ще спробуйте помістити регулярку в круглі дужки (), бо зазвичай шукає тільки те, що в дужках.

лексер будує ast - абстрактне синтаксичне дерево

ні, я не намагаюсь замінити [] на <>
я намагаюсь побудувати ast,
і що і як потім робитиму з отриманим списком - то уже окреме питання


[^\[]+?

все, окрім символу відкриваючої квадратної дужки


і ні, ця частина добре працює,
ви помиляєтесь

-----

Altair8800 написав:

Якщо не впевнені в регулярках, перевіряйте себе на онлайн-сервісах, таких як цей https://regexr.com/

приїхали) я на таких сервісах живу, коли хоть якусь регулярку пишу))


-----

моє останнє прохання було - допоможіть поради правильно на українську перекласти :[

https://blog.clever-games.win/
Це ще не кінець. Це навіть не початок кінця. Але, можливо, це кінець початку.
Зростання мудрості можна точно вимірювати ступенем зменшення злоби.