# recipe 検討例 ## 注意事項 この文章は古いものであり、現在の仕様を表すものではない。 アイデアの参考にするためだけに残す。 ## GA的トーク決定アルゴリズム * 現在の状態と、新たに選択されたトークの属性を 交配させることにより、次に一致するトークを選ぶ。 #トーク(generator fn)は「・」か、「・・」で始まる #タイトル(「~」)は省略可能 #「:」以降は属性。状態と比較し、属性が一致しなければ対象外となる。 ・・今日のご飯 :会話、季節?夏~秋、時刻?夕方、好感度?お客さん~   今日のご飯は@今日のご飯$1 でした。   @1 って美味しいの? #単語(enum)辞書は「?」か、「??」で始まる。 ??今日のご飯  カレー  チャーハン  うどん ?好感度 無関心 普通 お客さん 気になる 好き 大好き ?不快度 無関心 いや 嫌い 大嫌い #「・」、「?」が1つのタイトルは重複不可 #「・・」、「??」は重複可能、マージされる ## recipe peg // 1:全体定義[start] start = eof / block start / comment_line start block = comment_line / // 2:行の定義 line = comment_line / element_line // 2.1:コメント行 // [#]で始まり、改行の手前で終わる。 comment_line = sharp !(eol)*:text eol // 2.2:会話行 // 0個以上の空白の後に、会話inline要素が列挙され、が列挙される。 element_line = b:blank e:element* { return ast.element_line({brank: b}, e, loc());} blank = s:SP* {return text(); } // 3.1:会話行:inline要素 element = text / keyword // 3.2:テキスト text = text:(esc / normal)+ { return ast.text(text.join(""), loc()); } esc = &(KEY_MARK KEY_MARK) . mark:. { return [mark]; } normal = NORMAL_CHAR+ { return text(); } // 3.3:キーワード // 3.3.1:キーワード全体定義 keyword = body:keyword_body SPLIT { return body; } keyword_mark = &KEY_MARK . keyword_body = keyword_mark item:keyword_item { return item.func(item.key, loc()); } keyword_item = keyword_local_anchor / keyword_local_jump / keyword_normal // 3.3.2:キーワード // 「@keyword」一般 keyword_normal = key:IDENTIFIER { return {key: key, func: ast.keyword_normal}; } // 3.3.3:キーワード // 「@-keyword」一致するローカルアンカーのいずれかに飛ぶ keyword_local_jump = (&LOCAL_JUMP_CHAR ) . key:IDENTIFIER { return {key: key, func: ast.keyword_local_jump}; } // 3.3.4:キーワード // 「@:keyword」ローカルアンカー keyword_local_anchor = (&LOCAL_ANCHOR_CHAR) . key:IDENTIFIER { return {key: key, func: ast.keyword_local_anchor}; } // 9:一般トークン BR = LineTerminatorSequence SP = WhiteSpace IDENTIFIER = a:Identifier {return a.name;} SPLIT = SP* / &BR KEY_MARK = [@@] KEY_CHAR = [^@@  \r\n] PRI_COMMENT = [##] NOT_BR = !BR . NORMAL_CHAR = [^@@¥\r\n] LOCAL_JUMP_CHAR = [-ー-] LOCAL_ANCHOR_CHAR = [::]