0

おはようございます。

現在、いくつかの基本的な Ruby 文法を記述しようとしていますが、解析スペースで行き詰っていますか? x = 1 + 1 を処理できますが、x=1+1 を
パーサーできません
。空間をパーサーするにはどうすればよいですか?
すべての端末の後に十分なスペースを追加しようとしました。しかし、それは解析できず、nilを与えます.....どうすれば修正できますか? どうもありがとうございました、良い一日を。


grammar Test
  rule main
     s assign
  end

  rule assign
     name:[a-z]+ s '=' s expression s
     {
      def to_ast
        Assign.new(name.text_value.to_sym, expression.to_ast)
      end
    }
  end


  rule expression
     add
  end


  rule add
     left:brackets s '+' s right:add s
     {
      def to_ast
        Add.new(left.to_ast, right.to_ast)
      end
    }
    /
    minus
  end

  rule minus
     left:brackets s '-' s right:minus s
     {
      def to_ast
        Minus.new(left.to_ast, right.to_ast)
      end
    }
    /
    brackets
  end

  rule brackets
      '(' s expression ')' s
      {
       def to_ast
          expression.to_ast
       end
     }
      /
    term
  end

  rule term
    number / variable
  end

  rule number
     [0-9]+ s
     {
      def to_ast
        Number.new(text_value.to_i)
      end
    }
  end

  rule variable
     [a-z]+ s
     {
      def to_ast
        Variable.new(text_value.to_sym)
      end
     }
  end

  rule newline
     s "\n"+ s
  end

  rule s
    [ \t]*
  end
end

このコードは問題を解決しました!!!!

4

1 に答える 1

2

スペース ルールを定義するだけでは十分ではありません。スペースがあればどこでも使用する必要があります。これは頻繁に発生するため、通常、必須のスペースには短いルール名を使用し、オプションのスペースにSは小文字バージョンを使用します。s

次に、原則として、最上位のルールでオプションのスペースを最初にスキップし、その後にスペースが続く可能性のあるすべてのターミナルの後にもう一度スキップします。ここでの終端は文字列、文字セットなどです。そのため、 、 、 の {} ブロックの開始時、および {} ブロックのassign前、さらに「=」、「-」、および「+」リテラルの後に、ルールへの呼び出しを追加して、スペースをスキップします。variablebooleannumbers

このポリシーは私にとってうまく機能します。最小限のスペースを持つテスト ケースと、最大限のスペースを持つ別のケース (考えられるすべての場所) を用意することをお勧めします。

于 2017-10-06T23:58:38.890 に答える