Поиск слов в верхушке дерева - не найдено ни одного совпадения - PullRequest
1 голос
/ 23 августа 2011

Я столкнулся с немного странной ситуацией.

Я пытаюсь разобрать измерения, используя верхушку дерева.

Например - 6 'из 1/2 "Медной трубы, конечно, это также можно записать в футах, футах, дюймах, дюймах, дюймах, дюймах и т. Д. И т. Д.

У меня есть правило

rule measurement
      ('\'' / 'Foot' / 'foot' / 'Feet' / 'feet' / 
       '"' / 'Inches' / 'inches' /  'Inch' / 'inch' /
       'cm' / 'cms' / 'Centimeters' / 'centimeters' /  'Centimeter' / 'centimeter' / 
       'm' / 'ms' / 'Meters' / 'meters'/ 'Meter' / 'meter' / 
       'lb' / 'lbs' /  'Pounds' / 'pounds' / 'Pound' / 'pound' )
       (s? ')' / s) {
                    def value
                          [:measurement, text_value]
                    end
                    }
end

rule space
    [\s]+
end

Когда я ввожу «6 дюймов», «6 фунтов», «6 метров», все отлично работает, и я получаю свой номер и результаты измерений.

Когда я ввожу «6 метров», метры не анализируются должным образом.

Большинство измерений работают нормально, пропускаются только «метры» и «фунт» в измерениях, которые я здесь предоставил (но яуверен, что в будущем я добавлю больше измерений.

Любые идеи о том, почему я буду испытывать это?

В соответствии с запросом, более урезанная версияполная грамматика

grammar FullMeasurements
       rule full_product
           measures s? alternate_measure product_name {
             def value
                  [:full_product, text_value]
             end
           }

       end

       rule measures
        single_measure / dual_measure / quantity {
            def measures
                [:measures, text_value] unless text_value.blank?
            end
        }
    end


    rule dual_measure
        quantity s? single_measure {
            def value
                [:dual_measure, text_value] unless text_value.blank?
            end

            }
    end


    rule alternate_measure 
        '(' s? single_measure {
            def value
                [:alternate_measure, text_value] unless text_value.blank?
            end
        }
    end

    rule single_measure 
        (range_number / number) s? measurement optional_secondary_measurements  {
            def value
                [:single_measure, text_value]
            end
        }
    end

    rule optional_secondary_measurements
        measurement? {
            def value
                [:optional_secondary_measurements, text_value]
            end
        }
    end



    rule quantity
        (range_number / number) s? divisor? {
            def value
                [:quantity, text_value]
            end
        }
    end

        rule measurement
              ('\'' / 'Foot' / 'foot' / 'Feet' / 'feet' / 
               '"' / 'Inches' / 'inches' /  'Inch' / 'inch' /
               'cm' / 'cms' / 'Centimeters' / 'centimeters' /  'Centimeter' / 'centimeter' / 
               'm' / 'ms' / 'Meters' / 'meters'/ 'Meter' / 'meter' / 
               'lb' / 'lbs' /  'Pounds' / 'pounds' / 'Pound' / 'pound' )
                (s? ')' / s) {
                    def value
                          [:measurement, text_value]
                    end
                    }
         end



        rule divisor
        "x" 
    end

    rule product_name
            !measures words+ {
            def value
                [:product_name, text_value]
            end
        }
    end


    rule number 
     frac_number / regular_number optional_frac {
            def value
                [:number, text_value]
            end
        }
        end



        rule optional_frac
        frac_number? {
            def value
                [:optional_frac, text_value]
            end
        }
         end



         rule frac_number
        (s? regular_number '/' regular_number)  {
            def value
                [:frac_number, text_value]
            end
        }
        end

        rule words
        [0-9a-zA-Z\-()&.%'*\s]+ {
            def value
                text_value
            end 
        }

          end

        rule regular_number
        [0-9\.]+ {
            def value
                text_value
            end 
        }

        end

        rule space
          [\s]+
         end
end

Ответы [ 2 ]

1 голос
/ 23 августа 2011

Поскольку PEG являются жадными, а / является чередованием , упорядоченным , ваше правило measurement соответствует буквальному тексту "метра", и ваша грамматика не выполняется, поскольку не может найти следующее правило, соответствующее левому над "с". В отличие от регулярных выражений, PEG не будут возвращаться к предыдущим успешным совпадениям при неудачном.

Переключите порядок элементов в вашем правиле, чтобы сначала было множественное число, и вы должны быть в порядке.

0 голосов
/ 06 мая 2015

Phrogz был на правильном пути, но это не "метр", который сопоставляется первым, а "m", который не оставляет ничего, чтобы соответствовать "eter" или "eters", которые остались.

...