1

私は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
4

2 に答える 2

1

ParseKitの開発者はこちら。

文法が意味的に正しいかどうかを判断するために、入力例を詳しく調べていません。

ただし、既存の文法には 2 つの重大な構文上の問題があることがわかります


まず、この行には左再帰 (および引用符で囲まれていない の構文エラー/)が含まれています。

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

左再帰を削除するには、この行を次のように変更する必要があります。

units = unit ('/' unit)*;

ParseKit grammars で Left Recursion を排除する方法の詳細については、以前の回答を参照してください。


第二に、この行は次を使用して「空の」一致を許可しようとしていると思います''

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

これは、ParseKit 文法ではサポートされていない構文です。この機能は完全にサポートされていますが、構文はEmpty次のようになります。

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

それが役立つことを願っています。

于 2013-02-26T22:49:42.207 に答える
1

私が unidata.ucar.edu で見つけたこの文法は、かなり公式に見えますが、扱いにくく、接頭辞や単位が含まれていません。

Unit-Spec: 無数の 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]*)?
于 2013-02-26T04:08:47.867 に答える