1

以下のように、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

パーサーが文字列ノードを返すことを期待していますが、パーサーが入力を理解できなかったようです。任意のアイデアをいただければ幸いです。

4

1 に答える 1

4

Treetop (および一般的な PEG) では、他のほとんどの構文解析形式とは異なり、 choice 演算子は order です。

だから、

rule value
  number / string
end

あなたは Treetop によりも好む numberことを伝えていますstring

入力は で始まり、と(を通じて) の両方1に一致しますが、Treetop に解釈を優先するように指示したため、 として解析します。入力の に関しては、適用するルールがこれ以上ないため、何も返しません ( )。これは、Treetop では入力ストリーム全体を消費しないことはエラーであるためです。 numberstringwordnumbernumberanil

単純に選択の順序を逆にすると、入力全体が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

これにより、おおよそ次のような AST が得られます。

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"
于 2010-12-23T00:23:54.093 に答える