оптимизация парсинга строк: ruby - PullRequest
0 голосов
/ 22 декабря 2011

Я работаю над парсером, который в настоящее время работает слишком медленно для моих нужд (например, в 40 раз медленнее, чем хотелось бы) и хотел бы получить совет по методам увеличения моей скорости. Я пытался и в настоящее время использую пользовательский анализатор регулярных выражений , а также пользовательский анализатор, использующий strscanner class . Я слышал много положительных комментариев к treetop и рассмотрел попытку объединить регулярное выражение в одно огромное регулярное выражение, которое бы охватывало все совпадения, но хотел бы получить некоторую обратную связь с опытом прежде, чем я переписываю свой парсер еще раз.

Основные правила строк, которые я анализирую:

  • 3 сегмента (операторы BoL, сообщения, операторы EoL)
  • ~ 6 операторов BoL Операторы BoL могут быть в любом порядке
  • 2 оператора EoL Операторы EoL могут быть в любом порядке
  • Количество любого конкретного оператора может быть 0, 1 или> 1, но используется только 1, остальные удаляются и отбрасываются
  • Операторы в разделе 'message' строки не фиксируются / удаляются
  • Пробелы разрешены до и после операторов, но не обязательны
  • Некоторые операторы BoL могут иметь пробел в настройке

Мой текущий синтаксический анализатор Regex работает, пропуская строку через цикл, который проверяет операторы BoL или EoL 1 за один раз, и вырезает их, завершая цикл, когда больше нет операторов данного типа, так что ... 1027 *

loop{ 
if input =~ /^\s+/ then input.gsub!(/^\s+/,'') end
if input =~ /reges for operator_a/ #sets 
   sets operator_a
   input.gsub!(/regex for operator_a)/, '')
elsif input =~ /regex for operator_b/ 
   sets operator_b
   input.gsub!(/regex for operator_b/,'')
elsif input =~ /regex for operator_c/
   sets operator_c
   etc .. etc .. etc..
else
break
end
}

У меня вопрос: как лучше всего оптимизировать этот код? Treetop, еще одна библиотека / гем, которую я еще не нашел, объединяя циклы в одно огромное регулярное выражение, что-то еще?

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

Более конкретные грамматики / примеры, если это поможет. Это для анализа команд связи, отправляемых в игру пользователями, пока единственными командами являются, скажем, и шепот. Допускаются начальные операторы строк: :: {target},: {adverb}, = {verb} и # {direction of}. Операторы конца строки: {emoticon (aka.: D :( :)}, который устанавливает наречие, если еще не установлено, и пунктуацию конца строки, которая устанавливает глагол, если еще не установлен. персонаж 'это псевдоним для say, а sayto это псевдоним для say :: примеры:

': happy :: мой меч = как # мой шлем работают операторы Bol.

{:action=>:say, :adverb=>"happily", :verb=>"ask", :direction=>"my helm", :message=>"Bol command operators work."}

скажи да скажи работает

{:action=>:say, :message=>" yep say works"}

скажем, мой меч да да, он работает так же, как и операторы EoL!:)

{:action=>:say, :target=>"my sword", :adverb=>"happily", :verb=>"say", :message=>"yep sayto works as do EoL operators!"}

шепот :: мой друг: счастливые операторы команды Бол работают с Шепот.

{:action=>:whisper, :target=>"my friend", :adverb=>"happily", :message=>"Bol command operators work with whisper."}

шепотом: happy :: tinkerbell, и они работают в другом порядке.

{:action=>:whisper, :adverb=>"happily", :target=>"tinkerbell", :message=>"and they work in a different order."}

': bash = exclaim :: hammer BoL операторы тоже работают в этом порядке.

{:action=>:say, :adverb=>"bashfully", :verb=>"exclaim", :target=>"hammer", :message=>"BoL operators work in this order too."}

sayto bells = say: sad #wontwork Bol> Eol и направил! Работать с направленного? :)

{:action=>:say, :verb=>"say", :adverb=>"sadly", :direction=>"wontwork", :message=>"Bol > Eol and directed !work with directional?"}

'все EoL удалены ближе к концу, использованы и повторно вставлены. !! ??!? ....... :) ? (

{:action=>:say, :adverb=>"sadly", :verb=>"ask", :message=>"all EoL removed closest to end used and reinserted?"}

1 Ответ

3 голосов
/ 23 декабря 2011

Может быть, этот синтаксис полезен в вашем случае:

emoti_convert = { ":)" => "happily", ":(" => "sadly" }
re_emoti = Regexp.union(emoti_convert.keys)
str = "It does not work :(. Oh, it does :)!"

p str.gsub(re_emoti, emoti_convert)
#=> "It does not work sadly. Oh, it does happily!"

Но если вы пытаетесь определить грамматику, это не лучший способ (согласиться с комментариями @Dave Newton).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...