1

私はちょっと奇妙な状況に遭遇しました。

ツリートップを使用して測定値を解析しようとしています。

たとえば、6 フィートの 1/2 インチの銅パイプはもちろん、フィート、フィート、インチ、インチ、インチ、インチなどと表記することもできます。

だから私にはルールがある

ルール測定
      ('\'' / '足' / '足' / '足' / '足' /
       '"' / 'インチ' / 'インチ' / 'インチ' / 'インチ' /
       'cm' / 'cms' / 'センチメートル' / 'センチメートル' / 'センチメートル' / 'センチメートル' /
       「メートル」/「ミリ秒」/「メートル」/「メートル」/「メートル」/「メートル」/
       'ポンド' / 'ポンド' / 'ポンド' / 'ポンド' / 'ポンド' / 'ポンド' )
       (s? ')' / s) {
                    デフォルト値
                          [:測定、テキスト_値]
                    終わり
                    }
終わり

ルールスペース
    [\s]+
終わり

「6 インチ」、「6 ポンド」、「6 メートル」と入力すると、すべて正常に機能し、数値と測定値が返されます。

「6 メートル」と入力すると、メートルが正しく解析されません。

ほとんどの測定値は正常に機能します。ここで提供した測定値では、「メートル」と「ポンド」だけが欠落しています (ただし、将来さらに測定値を追加すると確信しています.

なぜ私がこれを経験するのかについてのアイデアはありますか?

リクエストに応じて、完全な文法のより「簡素化された」バージョン

文法 FullMeasurements
       ルール full_product
           対策?代替測定製品名 {
             デフォルト値
                  [:full_product, text_value]
             終わり
           }

       終わり

       ルール対策
        single_measure / dual_measure / 数量 {
            デフ対策
                [:measures, text_value] text_value.blank 以外?
            終わり
        }
    終わり


    ルール Dual_measure
        数量は?single_measure {
            デフォルト値
                [:dual_measure, text_value] text_value.blank?
            終わり

            }
    終わり


    ルールの代替測定
        '('s? single_measure {
            デフォルト値
                [:alternate_measure, text_value] text_value.blank でない限り?
            終わり
        }
    終わり

    ルール single_measure
        (range_number / number) s? 測定optional_secondary_measurements {
            デフォルト値
                [:single_measure, text_value]
            終わり
        }
    終わり

    ルール optional_secondary_measurements
        計測?{
            デフォルト値
                [:optional_secondary_measurements, text_value]
            終わり
        }
    終わり



    ルール数量
        (range_number / number) s? 除数?{
            デフォルト値
                [:数量, テキスト値]
            終わり
        }
    終わり

        ルール測定
              ('\'' / '足' / '足' / '足' / '足' /
               '"' / 'インチ' / 'インチ' / 'インチ' / 'インチ' /
               'cm' / 'cms' / 'センチメートル' / 'センチメートル' / 'センチメートル' / 'センチメートル' /
               「メートル」/「ミリ秒」/「メートル」/「メートル」/「メートル」/「メートル」/
               'ポンド' / 'ポンド' / 'ポンド' / 'ポンド' / 'ポンド' / 'ポンド' )
                (s? ')' / s) {
                    デフォルト値
                          [:測定、テキスト_値]
                    終わり
                    }
         終わり



        規則除数
        "バツ"
    終わり

    ルール product_name
            !言葉を測る+ {
            デフォルト値
                [:製品名, テキスト値]
            終わり
        }
    終わり


    ルール番号
     frac_number / regular_number optional_frac {
            デフォルト値
                [:number, text_value]
            終わり
        }
        終わり



        ルール optional_frac
        frac_number? {
            デフォルト値
                [:optional_frac, text_value]
            終わり
        }
         終わり



         ルール frac_number
        (s? レギュラー番号 '/' レギュラー番号) {
            デフォルト値
                [:frac_number, text_value]
            終わり
        }
        終わり

        ルールワード
        [0-9a-zA-Z\-()&.%'*\s]+ {
            デフォルト値
                テキスト値
            終わり
        }

          終わり

        ルール規則番号
        [0-9\.]+ {
            デフォルト値
                テキスト値
            終わり
        }

        終わり

        ルールスペース
          [\s]+
         終わり
終わり
4

2 に答える 2

1

PEGは貪欲で/順序付けられた代替であるため、measurementルールはリテラルテキスト「meter」に一致し、残りの「s」に一致する次のルールが見つからないため、文法は失敗します。正規表現とは異なり、PEGは、後の一致が失敗したときに、前の成功した一致をバックトラックしません。

ルール内のアイテムの順序を切り替えて、最初に複数形を使用します。これで問題ありません。

于 2011-08-22T21:16:34.877 に答える
0

Phrogz は正しい軌道に乗っていましたが、最初に一致したのは "meter" ではなく、残った "eter" または "eters" と一致するものが何も残っていない 'm' です。

于 2015-05-06T02:18:50.333 に答える