разделить строку кода и строчный комментарий в конце этой строки RegExp-ом, или как-то еще?

Здесь обсуждаются темы, косвенно связанные с Far.
User avatar
citRiks
Posts: 1733
Joined: Fri 25 Oct, 2019 18:18
Has thanked: 610 times
Been thanked: 102 times

разделить строку кода и строчный комментарий в конце этой строки RegExp-ом, или как-то еще?

Post by citRiks »

John Doe, Это понятно что изобретать велосипеды это плохая практика.
И все же, стоит ли так углублятся,
если предложенное мною выглядит достаточно просто, не?
User avatar
buniak_a_h
Posts: 4236
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 222 times
Been thanked: 643 times
Contact:

разделить строку кода и строчный комментарий в конце этой строки RegExp-ом, или как-то еще?

Post by buniak_a_h »

citRiks wrote: Thu 18 Feb, 2021 08:28 может нужно тупа сделать итерацию такую по всем буквам с начала:…
Именно так и устроена та прога, что я Вам посылал.
User avatar
John Doe
Бюрократ
Posts: 13807
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 426 times
Contact:

разделить строку кода и строчный комментарий в конце этой строки RegExp-ом, или как-то еще?

Post by John Doe »

citRiks wrote: Thu 18 Feb, 2021 09:49 И все же, стоит ли так углублятся,
Зависит от того насколько строго должен быть осуществлён отбор, плюс сколько времени вы готовы дополнительно потом инвестировать в доводку своего велосипеда, при каждой встрече с нетипичным случаем.

Замечу также, что модуль luacheck, который наверняка у вас тоже установлен, содержит и парсер, и лексер (но как приспосособить их интерфейсы к вашей задаче сходу не скажу конечно).
https://t.me/FarManager — Telegram чат
User avatar
buniak_a_h
Posts: 4236
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 222 times
Been thanked: 643 times
Contact:

разделить строку кода и строчный комментарий в конце этой строки RegExp-ом, или как-то еще?

Post by buniak_a_h »

citRiks wrote: Thu 18 Feb, 2021 10:27 buniak_a_h, это LuaComplete или то что на паскале?
Это то, что на паскале.
User avatar
citRiks
Posts: 1733
Joined: Fri 25 Oct, 2019 18:18
Has thanked: 610 times
Been thanked: 102 times

разделить строку кода и строчный комментарий в конце этой строки RegExp-ом, или как-то еще?

Post by citRiks »

John Doe wrote: Thu 18 Feb, 2021 11:47Зависит от того насколько строго должен быть осуществлён отбор, плюс сколько времени вы готовы дополнительно потом инвестировать в доводку своего велосипеда, при каждой встрече с нетипичным случаем.
как всегда прав, а я как всегда захотел протестировать свои speed coding abilities, с как всегда удручающим успехом.
За три часа :-( включая перерывы, получилось такое нa C# ,
на условия задачи отвечает целиком и полностью,
учитываются блочные строки и комментарии
  1. static void _lua_code_cmnt_line_dissect(string sz_inp_lua_str, out int int_out_pos_idx_cmnt, out string sz_out_lua_code, out string sz_out_lua_cmnt, out string sz_out_lua_mask)
  2.  
  3. {
  4.  
  5.     StringBuilder sb_mask_quoted = new StringBuilder();
  6.  
  7.     sz_out_lua_code = "";
  8.  
  9.     sz_out_lua_cmnt = "";
  10.  
  11.     sz_out_lua_mask = "";
  12.  
  13.     int_out_pos_idx_cmnt = -1;
  14.  
  15.     List<char> lst_quotes = new List<char>() { '\'', '"' };
  16.  
  17.     rgx.Regex rgx_flow_start = new rgx.Regex(@"^\[=*\[");
  18.  
  19.     const char
  20.  
  21.         CH_ESCAPE = '\\',
  22.  
  23.         CH_QUOTE_NONE = 'x',
  24.  
  25.         CH_QUOTE_MASK = '#',
  26.  
  27.         CH_CMT_START = '-',
  28.  
  29.         CH_BLK_START = '[',
  30.  
  31.         CH_BLK_FINAL = ']';
  32.  
  33.     const string STR_CMT_MARK_LINE = "--";
  34.  
  35.     char ch_quote_curr = CH_QUOTE_NONE, ii_ch;
  36.  
  37.     int cnt_escape = 0;
  38.  
  39.     string sz_cur_blk_beg = null, sz_cur_blk_end = null;
  40.  
  41.     for (int ii = 0; ii < sz_inp_lua_str.Length; ii++)
  42.  
  43.     {
  44.  
  45.         ii_ch = sz_inp_lua_str[ii];
  46.  
  47.         // we are inside quotes:
  48.  
  49.         if (ch_quote_curr != CH_QUOTE_NONE)
  50.  
  51.         {
  52.  
  53.             if (ii_ch == CH_ESCAPE)
  54.  
  55.             { // \', \"
  56.  
  57.                 cnt_escape += 1;
  58.  
  59.             }
  60.  
  61.             else
  62.  
  63.             {
  64.  
  65.                 if (cnt_escape == 0)
  66.  
  67.                 {
  68.  
  69.                     if (ii_ch == ch_quote_curr)
  70.  
  71.                         ch_quote_curr = CH_QUOTE_NONE;
  72.  
  73.                 }
  74.  
  75.                 else
  76.  
  77.                 {
  78.  
  79.                     cnt_escape = 0;
  80.  
  81.                 }
  82.  
  83.             }
  84.  
  85.             ii_ch = CH_QUOTE_MASK;
  86.  
  87.         }
  88.  
  89.         else if (sz_cur_blk_end != null)
  90.  
  91.         { // we are inside some flow block here
  92.  
  93.             if (
  94.  
  95.                 // this is ']' character here:
  96.  
  97.                 ii_ch == CH_BLK_FINAL &&
  98.  
  99.                 // the current substring matches required block end:
  100.  
  101.                 sz_inp_lua_str.Substring(ii).StartsWith(sz_cur_blk_end)
  102.  
  103.                     )
  104.  
  105.             {
  106.  
  107.                 { /* just skip end block mark characters.
  108.  
  109.                     Not too elegant, but let it be this way: */
  110.  
  111.                     for (int jj = 0; jj < sz_cur_blk_end.Length; jj++)
  112.  
  113.                         sb_mask_quoted.Append(CH_QUOTE_MASK);
  114.  
  115.                     ii += sz_cur_blk_end.Length - 1;
  116.  
  117.                 }
  118.  
  119.                 // this cancels flow block indication:
  120.  
  121.                 sz_cur_blk_beg = sz_cur_blk_end = null;
  122.  
  123.                 continue;
  124.  
  125.             }
  126.  
  127.             else
  128.  
  129.             {
  130.  
  131.                 ii_ch = CH_QUOTE_MASK;
  132.  
  133.             }
  134.  
  135.         }
  136.  
  137.         else
  138.  
  139.         { // we are not in quotes and not in flow block
  140.  
  141.             if (lst_quotes.Contains(ii_ch))
  142.  
  143.             { // we met single quote character
  144.  
  145.                 ch_quote_curr = ii_ch;
  146.  
  147.                 ii_ch = CH_QUOTE_MASK;
  148.  
  149.             }
  150.  
  151.             else if (ii_ch == CH_BLK_START)
  152.  
  153.             { // propbably we should start flow block?
  154.  
  155.                 rgx.Match rem_block_start = rgx_flow_start.Match(sz_inp_lua_str.Substring(ii));
  156.  
  157.                 if (rem_block_start.Success)
  158.  
  159.                 { // this is flow block indeed!
  160.  
  161.                     sz_cur_blk_beg = rem_block_start.Value;
  162.  
  163.                     sz_cur_blk_end = sz_cur_blk_beg.Replace(CH_BLK_START, CH_BLK_FINAL);
  164.  
  165.                     ii_ch = CH_QUOTE_MASK;
  166.  
  167.                 }
  168.  
  169.             }
  170.  
  171.             else if (
  172.  
  173.                 // this is '-' character here?
  174.  
  175.                 ii_ch == CH_CMT_START &&
  176.  
  177.                 // this is "--" string here?
  178.  
  179.                 sz_inp_lua_str.Substring(ii).StartsWith(STR_CMT_MARK_LINE))
  180.  
  181.             {
  182.  
  183.                 if (rgx_flow_start.IsMatch(sz_inp_lua_str.Substring(ii + STR_CMT_MARK_LINE.Length)))
  184.  
  185.                 { /* this is --[=*[ here, consider it as flow block, and mask starting "--".
  186.  
  187.                     Similar treatment to "if block end .." handler above */
  188.  
  189.                     for (int jj = 0; jj < STR_CMT_MARK_LINE.Length; jj++)
  190.  
  191.                         sb_mask_quoted.Append(CH_QUOTE_MASK);
  192.  
  193.                     ii += STR_CMT_MARK_LINE.Length - 1;
  194.  
  195.                     continue;
  196.  
  197.                 }
  198.  
  199.                 else
  200.  
  201.                 { // got it! this is conventional in-line comment after "--":
  202.  
  203.                     int_out_pos_idx_cmnt = ii;
  204.  
  205.                     sz_out_lua_code = sz_inp_lua_str.Substring(0, int_out_pos_idx_cmnt);
  206.  
  207.                     sz_out_lua_cmnt = sz_inp_lua_str.Substring(int_out_pos_idx_cmnt);
  208.  
  209.                     sb_mask_quoted.Append(sz_out_lua_cmnt);
  210.  
  211.                     break;
  212.  
  213.                 }
  214.  
  215.             }
  216.  
  217.             else
  218.  
  219.             {
  220.  
  221.                 /* this is just lua code statements,
  222.  
  223.                 no inside any block, not inside any quotes,
  224.  
  225.                 nothing to do */
  226.  
  227.             }
  228.  
  229.         }
  230.  
  231.         sb_mask_quoted.Append(ii_ch);
  232.  
  233.     }
  234.  
  235.     sz_out_lua_mask = sb_mask_quoted.ToString();
  236.  
  237. } // _lua_code_cmnt_line_dissect
input:
local a1 = [[ -- aaa -- bbb ccc ]] xxx --[[ hello ? ]] yyy --[===[ hello 222 ]===] -- line comment here
output:
int_out_pos_idx_cmnt = 83 sz_out_lua_code = "local a1 = [[ -- aaa -- bbb ccc ]] xxx --[[ hello ? ]] yyy --[===[ hello 222 ]===] " sz_out_lua_cmnt = "-- line comment here" sz_out_lua_mask = "local a1 = ####################### xxx ############### yyy ####################### -- line comment here"
PS
одинарных кавычек в примере нету, так как это "слишком легко", были в первых тестах,
а скопипастил я второй и более сложный тест на flow block, которые по сути много-символьные кавычки.
Не прогоняя еще раз, просто напишу так:

input:
local a1 = ' -- aaa -- bbb ccc '..xxx --[[ hello ? ]]..yyy..[[ hello 222 ]] -- line comment here
output:
int_out_pos_idx_cmnt = 77 sz_out_lua_code = "local a1 = ' -- aaa -- bbb ccc '..xxx --[[ hello ? ]]..yyy..[[ hello 222 ]] " sz_out_lua_cmnt = "-- line comment here" sz_out_lua_mask = "local a1 = #####################..xxx ###############..yyy..############### -- line comment here"
UPDATE 21/03/2021
Немного косметики
Last edited by citRiks on Sat 20 Mar, 2021 23:06, edited 3 times in total.
User avatar
citRiks
Posts: 1733
Joined: Fri 25 Oct, 2019 18:18
Has thanked: 610 times
Been thanked: 102 times

разделить строку кода и строчный комментарий в конце этой строки RegExp-ом, или как-то еще?

Post by citRiks »

buniak_a_h wrote: Wed 17 Feb, 2021 17:23 P/S. Вот такие паттерны работают:
Line:match([[^(.*%b"".-)%-%-]]), regex.match(Line, [[^(.*['"].*['"].*)--]])
Если несколько литералов - работают тоже.
Первый работает только для литералов, заключённых в двойные кавычки.
Второй не будет работать, если внутри литерала с одним типом кавычек имеется символ другой (здесь «кавычками» я называю и апостроф ', и кавычки ")
в копилку паттернов, это взято из МобДебуг @П.Кульченко:
-- remove block comments: :gsub("%-%-%[(=*)%[.-%]%1%]", "") -- remove line comments :gsub("%-%-.-\n", " ")
Взято откуда-то:
-- remove line comments: :gsub(s, "%-%-+(.*)$", "%1") :gsub(s, "%-%-+ ?(.*)$", "%1")
User avatar
citRiks
Posts: 1733
Joined: Fri 25 Oct, 2019 18:18
Has thanked: 610 times
Been thanked: 102 times

разделить строку кода и строчный комментарий в конце этой строки RegExp-ом, или как-то еще?

Post by citRiks »

PS2
Кажется что наиболее разумно было бы решать подобное через LPEG все же,
с прибавочной стоимостью "знать LPEG".
если бы уже в процесс писания я не вспомнил бы про проблему "блочные/потоковые каменты и кавычки", написал бы через LPEG, но увы ..
Shmuel
Posts: 6819
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 528 times

разделить строку кода и строчный комментарий в конце этой строки RegExp-ом, или как-то еще?

Post by Shmuel »

В мануале LPeg есть готовый пример для Lua's long strings. Модифицировать его для комментариев должно быть очень просто.
User avatar
buniak_a_h
Posts: 4236
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 222 times
Been thanked: 643 times
Contact:

разделить строку кода и строчный комментарий в конце этой строки RegExp-ом, или как-то еще?

Post by buniak_a_h »

citRiks wrote: Sat 20 Mar, 2021 18:53 наиболее разумно было бы решать подобное через LPEG все же
1. Я не знаю, что такое LPEG. Предположил, что язык регэкспов.
2. А как быть с литералами? А, например, --[[qqq]] - это блочный комментарий, а ---[[qqq]] - строковый.
3. А ещё блочные комменты и литералы [[…]] могут быть многострочными.
Вам же писали:
John Doe wrote: Thu 18 Feb, 2021 11:47 Зависит от того насколько строго должен быть осуществлён отбор
Last edited by buniak_a_h on Sat 20 Mar, 2021 20:00, edited 1 time in total.
User avatar
citRiks
Posts: 1733
Joined: Fri 25 Oct, 2019 18:18
Has thanked: 610 times
Been thanked: 102 times

разделить строку кода и строчный комментарий в конце этой строки RegExp-ом, или как-то еще?

Post by citRiks »

ваши замечания имеют смысл, рад прояснить
buniak_a_h wrote: Sat 20 Mar, 2021 19:58 1. Я не знаю, что такое LPEG. Предположил, что язык регэкспов.
Parsing Expression Grammar,
лексический анализ, парсит структуру (грамматику) языков, текстовые форматы
buniak_a_h wrote: Sat 20 Mar, 2021 19:58 2. А как быть с литералами? А, например, --[[qqq]] - это блочный комментарий, а ---[[qqq]] - строковый.
3. А ещё блочные комменты и литералы [[…]] могут быть многострочными.
* такую элементарщину даже я в своем коде выше решил :)
* многострочность - это просто другая буква для пробела, так же как и, например, ТАБ
buniak_a_h wrote: Sat 20 Mar, 2021 19:58 Вам же писали:
John Doe писал(а): ↑Чт 18 фев, 2021 13:47
Зависит от того насколько строго должен быть осуществлён отбор
у меня в приведенном коде все строго, прямо как в детском саду :)
Last edited by citRiks on Sat 20 Mar, 2021 22:26, edited 1 time in total.
Post Reply

Return to “Операционные системы, командные оболочки и прочее”