Я считаю, что это должно быть одно правило в Treetop - PullRequest
1 голос
/ 13 июля 2011

У меня есть эта рабочая пара правил в Treetop, которую перфекционист во мне считает, что это должно быть одно-единственное правило или, может быть, что-то более красивое, по крайней мере:

rule _
  crap
  /
  " "*
end

rule crap
  " "* "\\x0D\\x0A"* " "*
end

Я анализирую некоторые выражения, которые время от времени заканчиваются на "\ x0D \ x0A". Да, не "\ r \ n", а "\ x0D \ x0A". Что-то удвоилось в какой-то момент. Длинная история.

Это правило работает, но оно уродливо и беспокоит меня. Я попробовал это:

rule _
  " "* "\\x0D\\x0A"* " "*
  /
  " "*
end

что вызвало

SyntaxError: (eval):1276:in `load_from_string': compile error
(eval):1161: class/module name must be CONSTANT
    from /.../gems/treetop-1.4.9/lib/treetop/compiler/grammar_compiler.rb:42:in `load_from_string'
    from /.../gems/treetop-1.4.9/lib/treetop/compiler/grammar_compiler.rb:35:in `load'
    from /.../gems/treetop-1.4.9/lib/treetop/compiler/grammar_compiler.rb:32:in `open'
    from /.../gems/treetop-1.4.9/lib/treetop/compiler/grammar_compiler.rb:32:in `load'

В идеале я хотел бы написать что-то вроде:

rule _
  (" " | "\\x0D\\x0A")*
end

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

rule _
  " "*
  /
  "\n"*
end

, который будет соответствовать "", но никогда \ n.

Ответы [ 2 ]

1 голос
/ 13 июля 2011

Я вижу, что вы используете три разных OR символа: /, | и \ (из которых только первое означает OR).

Это отлично работает:

grammar Language

  rule crap
    (" " / "\\x0D\\x0A")* {
      def value
        text_value    
      end
    }
  end

end
#!/usr/bin/env ruby

require 'rubygems'
require 'treetop'
require 'polyglot'
require 'language'

parser = LanguageParser.new
value = parser.parse(' \\x0D\\x0A   \\x0D\\x0A   ').value
print '>' + value + '<'

печать:

> \x0D\x0A   \x0D\x0A   <
0 голосов
/ 06 мая 2015

Вы сказали: «Я также обнаружил, что у вас не может быть только одного * на правило» (вы имеете в виду: вы МОЖЕТЕ иметь), «которое будет соответствовать», «но никогда \ n».

Ofкурс;правило успешно выполняется, когда оно совпадает с символами пробела.Вместо этого вы можете просто использовать +:

rule _
  " "+
  /
  "\n"*
end

Вы также можете заключить в скобки символы пробела, если хотите сопоставить любое количество символов пробела или новой строки:

rule _
  (" " / "\n")*
end

Ваша ошибка«имя класса / модуля должно быть CONSTANT», потому что имя правила используется в качестве префикса имени модуля, чтобы содержать любые методы, присоединенные к вашему правилу.Имя модуля не может начинаться со знака подчеркивания, поэтому нельзя использовать методы в правиле, имя которого начинается со знака подчеркивания.

...