LoginSignup
1

More than 5 years have passed since last update.

OPEG 標準コーディング規則

Last updated at Posted at 2017-04-07

本文について

  1. OPEG 文法開発者向けの規則集(案2017,内部情報)をまとめてある
  2. 今後、OPEG/IDE の整備により、改訂される可能性がある
  3. あいまいな点は、公開 OPEGファイルを参考にして欲しい

非終端記号に関する名前慣習

OPEGは、宣言的な構文木構築記法をサポートしており、非終端記号は、名前から構文木の操作がわかるように区別する。

解析表現のみ

(構文木の構築をともなわない)解析表現は、英大文字からなる名前を用いる。

よい例
_ = [ \t]*
COMMENT = _ '#' ( !'\n' . )*
DIGIT = [0-9]

慣習として、空白系は _ アンダスコア名を用いる。

構文木のノード生成

構文木のノードを生成するときは、英大文字で始まるキャメルスタイルの名前をつける。

よい例
FuncDef = {
    "def" __ 
    $name(Name) __ 
    '(' <on InParentheses ( __ $(ParameterList)? __ )> ')' 
    ( _ '->' _ $type(Test) )?  __ 
    ':' __ $body(Suite) 
    #FuncDecl 
}

構文木の操作

構文木のノードを生成をともなわない構文木の操作は、アンダスコアで始まる名前をつける。

よい例
_Assign = 
    '+=' #AddAssign
    / '-=' #SubAssign
    / '*=' #MulAssign
    / '/=' #DivAssign
    / '%=' #ModAssign

解析表現文法

構文規則

構文規則の定義は、非終端記号の名前、空白(1文字), = まで同じ行で書く。 (この理由は、OPEGのIDEが未整備で、構文定義を検索しやすくため)

良い例
DIGIT = [0-9]
Digit = {
    [0-9]
    #Digit
}
望ましくない例
INTEGER 
    = [0]
    / [1-9] [0-9]*

次のように空白を揃えるのは、見た目が美しいが、構文定義を検索しやすくないのであまり望ましくない。

望ましくない例
NON_ZERO_DIGIT = [1-9]
DIGIT          = [0-9]
OCT_DIGIT      = [0-7]
HEX_DIGIT      = [0-9a-fA-F]
BIN_DIGIT      = [01]

選択

選択は、構文規則として抽出し、各解析表現ごとに改行することが望ましい。

よい例
EOS = 
    ';'
    / NEWLINE
    / COMMENT

もしインラインで選択を用いるときは、() で囲む。

EOS = (';' / NEWLINE / COMMENT)

ノード生成

ノード生成は、適切な解析表現で区切り、複数行にわけてインデントして記述する。

Integer = {
    (OCT_INTEGER / HEX_INTEGER / BIN_INTEGER / DECIMAL_INTEGER)
     #IntExpr
} [lL]? 

ノード生成がシンプルな場合は、1行で書いてもよい。

FloatNumber = { EXPONENT_FLOAT #DoubleExpr }

右折りたたみ(left-folding)

右折りたたみは、折りたたみ箇所で複数行にわけて書くのがよい。

Sum     = 
        Product 
        {$left ( "+" #AddExpr / "-" #SubExpr ) $right(Product) }*

タグ付け

タグ付けは、ノード生成の最後に書く。

FloatNumber = { EXPONENT_FLOAT #DoubleExpr }

パターンによってタグ付けが変わるときはこの限りではない。

Sum     = 
        Product 
        {$left ( "+" #AddExpr / "-" #SubExpr ) $right(Product) }*

また無理にタグを付ける必要はない。

OPEG ファイル

OPEG ファイルは、 スタート地点となる構文定義に始まり、トップダウンで構文規則を定義する。

一般的には、次のようなファイル構成となる。

  1. ライセンス、著作権表記、連絡先
  2. スタート解析表現
  3. (必要なら)ORIGAMI 定義
  4. コードレイアウト (空白や改行などの字句規則)
  5. 構文規則
    • トップレベル
    • ステートメント
    • リテラル

example 文

可読性があがるので、構文定義の前に example は必ず入れる。

example FuncDef '''
def sum_and_stringify(nums: List[int]) -> str:  
    """Adds up the numbers in a list and returns the result as a string."""
    return str(sum(nums))
'''

FuncDef = {
    "def" __ 
    $name(Name) __ 
    '(' <on InParentheses ( __ $(ParameterList)? __ )> ')' 
    ( _ '->' _ $type(Test) )?  __ 
    ':' __ $body(Suite) 
    #FuncDecl 
}

注意: 個々の構文定義ごとに example を入れる必要はない。 origami test コマンドでカバーされるようにexampleをいれる。

共有する

OPEG ファイルは、オープン文法の思想にもとづけば、公開して共有することが望ましい。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1