【问题标题】:BNF Grammar for units of measurement测量单位的 BNF 语法
【发布时间】:2013-02-27 10:44:43
【问题描述】:

我正在使用ParseKit 来解析度量单位。为了做到这一点,我必须提供一个语法。我尝试使用谷歌搜索,但这并没有让我走得太远。虽然这对我自己来说是一个有趣的练习,但我想确保我做对了。 ParseKit 期待这样的 BNF 语法:

@start  = number units;
units = unit+ | unit+ / unit+;
unit = prefix baseUnit | baseUnit;
prefix = '' | 'milli' | 'micro' | 'pico';
baseUnit = 'm' | 'meter' | 'g' | 'gram'

我希望支持以下输入:

25 m²
25 m^-3
25 m**-5/kg**-2
25 m/s squared
25 mm² per second
25 m/s
5 kg meters per second squared
3 m-kg/s^2
3 m kilograms

【问题讨论】:

  • 您是否正在寻求帮助来改进您发布的语法以使其完全支持您所需的输入?
  • @rmaddy 很高兴能参考官方/非官方语法,但欢迎改进。
  • 什么是mekge 是什么?
  • 您的语法不支持“秒”或“s”,但您想要的代码支持。你的前缀不包括'kg'的'kilo'(并且'kg'作为质量的基本单位而不是'g'是异常的。你没有混合电气单位(这不是一个大问题,因为我看到它;您没有任何电气示例)。您没有前缀的缩写。您可能会发现“mm”会导致问题(是米-米,毫-米,米-米或毫米)。您不支持复数形式(米、千克)。
  • @robmayoff:我认为'e'代表指数,是'^'等的替代品。我对此有点困惑;有缩写“e”的国际单位制单位吗?我不认为这是一个严重的问题,但有很多模棱两可的地方潜伏着。

标签: objective-c grammar units-of-measurement bnf parsekit


【解决方案1】:

ParseKit 的开发者在这里。

我没有仔细查看您的示例输入以确定您的语法在语义上是否正确。

但是,我确实看到了您现有语法的两个重要句法问题。


首先,此行包含左递归(以及未引用的/ 的语法错误):

units = unit+ | unit+ / unit+;  // Incorrect. Will not work.

您必须更改此行以将左递归删除为以下内容:

units = unit ('/' unit)*;

my prior answer for more information on eliminating Left Recursion in your ParseKit grammars


其次,我相信这条线试图通过使用'' 来允许“空”匹配:

prefix = '' | 'milli' | 'micro' | 'pico';   // Incorrect. Will not work.

ParseKit 语法中不支持这种语法。完全支持此功能,但语法为Empty,如:

prefix = Empty | 'milli' | 'micro' | 'pico';

希望对您有所帮助。

【讨论】:

  • 优秀。这澄清了一些事情。最后,我可以解析“皮克”之类的东西,但不能解析“皮克”。我在文档中没有看到任何关于如何解析子字符串的内容。
  • 我想我需要自定义 PKTokenizer 但我不知道从哪里开始。
  • 您可以先在此处标记我的答案正确(或至少赞成),然后提出一个关于标记化的新问题 :)。我会及时回答所有标记为ParseKit的问题。
【解决方案2】:

This grammar 我在 unidata.ucar.edu 上找到的看起来很正式,虽然笨拙,并且不包含前缀或单位。

单位规格:其中之一 没有什么 Shift-Spec

 Shift-Spec: one of
         Product-Spec
         Product-Spec SHIFT REAL
         Product-Spec SHIFT INT
         Product-Spec SHIFT Timestamp

 Product-Spec: one of
         Power-Spec
         Product-Spec Power-Spec
         Product-Spec MULTIPLY Power-Spec
         Product-Spec DIVIDE Power-Spec

 Power-Spec: one of
         Basic-Spec
         Basic-Spec INT
         Basic-Spec EXPONENT
         Basic-Spec RAISE INT

 Basic-Spec: one of
         ID
         "(" Shift-Spec ")"
         LOGREF Product_Spec ")"
         Number

 Number: one of
         INT
         REAL

 Timestamp: one of
         DATE
         DATE CLOCK
         DATE CLOCK CLOCK
         DATE CLOCK INT
         DATE CLOCK ID
         TIMESTAMP
         TIMESTAMP INT
         TIMESTAMP ID

 SHIFT:
         <space>* <shift_op> <space>*

 <shift_op>: one of
         "@"
         "after"
         "from"
         "since"
         "ref"

 REAL:
         the usual floating-point format

 INT:
         the usual integer format

 MULTIPLY: one of
         "-"
         "."
         "*"
         <space>+
         <centered middot>

 DIVIDE:
         <space>* <divide_op> <space>*

 <divide_op>: one of
         per
         PER
         "/"

 EXPONENT:
         ISO-8859-9 or UTF-8 encoded exponent characters

 RAISE: one of
         "^"
         "**"

 ID: one of
         <id>
         "%"
         "'"
         "\""
         degree sign
         greek mu character

 <id>:
         <alpha> <alphanum>*

 <alpha>:
         [A-Za-z_]
         ISO-8859-1 alphabetic characters
         non-breaking space

 <alphanum>: one of
         <alpha>
         <digit>

 <digit>:
         [0-9]

 LOGREF:
         <log> <space>* <logref>

 <log>: one of
         "log"
         "lg"
         "ln"
         "lb"

 <logref>:
         "(" <space>* <re> ":"? <space>*

 DATE:
         <year> "-" <month> ("-" <day>)?

 <year>:
         [+-]?[0-9]{1,4}

 <month>:
         "0"?[1-9]|1[0-2]

 <day>:
         "0"?[1-9]|[1-2][0-9]|"30"|"31"

 CLOCK:
         <hour> ":" <minute> (":" <second>)?

 TIMSTAMP:
         <year> (<month> <day>?)? "T" <hour> (<minute> <second>?)?

 <hour>:
         [+-]?[0-1]?[0-9]|2[0-3]

 <minute>:
         [0-5]?[0-9]

 <second>:
         (<minute>|60) (\.[0-9]*)?

【讨论】:

    猜你喜欢
    • 2016-02-12
    • 1970-01-01
    • 2014-11-09
    • 1970-01-01
    • 2010-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-17
    相关资源
    最近更新 更多