1

我遇到了一些奇怪的情况。

我正在尝试使用树梢解析测量值。

例如 - 6' of 1/2" Copper Pipe 当然,这也可以写成英尺、英尺、英寸、英寸、英寸、英寸等。

所以我有一个规则

规则测量
      ('\'' / '脚' / '脚' / '脚' / '脚' /
       '"' / '英寸' / '英寸' / '英寸' / '英寸' /
       'cm' / 'cms' / '厘米' / '厘米' / '厘米' / '厘米' /
       “米”/“毫秒”/“米”/“米”/“米”/“米”/
       “磅”/“磅”/“磅”/“磅”/“磅”/“磅”)
       (s?')' / s) {
                    默认值
                          [:测量,文本值]
                    结尾
                    }
结尾

规则空间
    [\s]+
结尾

当我输入“6 英寸”、“6 磅”、“6 米”时,一切正常,我得到了我的号码和测量值。

当我输入“6 米”时,没有正确解析米。

大多数测量结果都很好,我在这里提供的测量值中只有“米”和“磅”被遗漏了(但我相信我将来会添加更多的测量值。

关于我为什么会遇到这种情况的任何想法?

根据要求,完整语法的更“精简”版本

语法 FullMeasurements
       规则 full_product
           措施 s? 替代测量产品名称 {
             默认值
                  [:full_product, text_value]
             结尾
           }

       结尾

       规则措施
        single_measure / dual_measure / 数量 {
            定义措施
                [:measures, text_value] 除非 text_value.blank?
            结尾
        }
    结尾


    规则 dual_measure
        数量 s? 单一测量{
            默认值
                [:dual_measure, text_value] 除非 text_value.blank?
            结尾

            }
    结尾


    规则alternate_measure
        '('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) {
                    默认值
                          [:测量,文本值]
                    结尾
                    }
         结尾



        规则除数
        “X”
    结尾

    规则产品名称
            !测量单词+ {
            默认值
                [:产品名称,文本值]
            结尾
        }
    结尾


    规则编号
     frac_number / regular_number optional_frac {
            默认值
                [:数字,文本值]
            结尾
        }
        结尾



        规则 optional_frac
        frac_number?{
            默认值
                [:optional_frac, text_value]
            结尾
        }
         结尾



         规则 frac_number
        (s?regular_number '/'regular_number) {
            默认值
                [: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 was on the right track, but it's not "meter" being matched first, but 'm' that leaves nothing to match the "eter" or "eters" that's left over.

于 2015-05-06T02:18:50.333 回答