Treetop Ruby Parser - не мог разобрать заказанный выбор

StackOverflow https://stackoverflow.com/questions/4514663

  •  12-10-2019
  •  | 
  •  

Вопрос

Я определил простую грамматику для разбора строки и числа, используя TreeTop, как показано ниже.

grammar Simple
    rule value
        number / string
    end 

    rule string
        word space string
        /
        word
    end

    rule word
        [0-9a-zA-Z]+
    end

    rule number
        [1-9] [0-9]*
    end

    rule space
        ' '+
    end
end

Рубин:

parser = SimpleParser.new
parser.parse('123abc wer') # => nil

Я ожидаю, что парсер вернется строковый узел Но похож на анализатор не мог понять Вход. Любая идея будет оценена.

Это было полезно?

Решение

В Treetop (и в целом, на самом деле) оператор выбора упорядоченный, в отличие от большинства других формализмов.

Итак, в

rule value
  number / string
end

Вы говорите Treetop, что вы предпочитать number над string.

Ваш вход начинается с 1, что соответствует оба number а также string (через word), но вы сказали Treetop предпочесть number интерпретация, поэтому он анализирует это как number. Анкет Когда дело доходит до a при вводе у него больше нет правил для применения, и, таким образом, он ничего не возвращает (nil), потому что в Treetop это ошибка не потреблять весь входной поток.

Если вы просто отмените порядок выбора, весь вход будет интерпретироваться как string вместо number:

SyntaxNode+String0 offset=0, "123abc wer" (word,space,string):
  SyntaxNode offset=0, "123abc":
    SyntaxNode offset=0, "1"
    SyntaxNode offset=1, "2"
    SyntaxNode offset=2, "3"
    SyntaxNode offset=3, "a"
    SyntaxNode offset=4, "b"
    SyntaxNode offset=5, "c"
  SyntaxNode offset=6, " ":
    SyntaxNode offset=6, " "
  SyntaxNode offset=7, "wer":
    SyntaxNode offset=7, "w"
    SyntaxNode offset=8, "e"
    SyntaxNode offset=9, "r"

Или вы можете сохранить заказ таким, как он есть, но позволить value Правило подходит несколько раз. Либо вставьте новое правило верхнего уровня, как это:

rule values
  value+
end

или изменить value правило так:

rule value
  (number / string)+
end

Что даст вам примерно так:

SyntaxNode offset=0, "123abc wer":
  SyntaxNode+Number0 offset=0, "123":
    SyntaxNode offset=0, "1"
    SyntaxNode offset=1, "23":
      SyntaxNode offset=1, "2"
      SyntaxNode offset=2, "3"
      SyntaxNode+String0 offset=3, "abc wer" (word,space,string):
        SyntaxNode offset=3, "abc":
          SyntaxNode offset=3, "a"
          SyntaxNode offset=4, "b"
      SyntaxNode offset=5, "c"
    SyntaxNode offset=6, " ":
      SyntaxNode offset=6, " "
    SyntaxNode offset=7, "wer":
      SyntaxNode offset=7, "w"
      SyntaxNode offset=8, "e"
      SyntaxNode offset=9, "r"
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top