ゆうげんおーとまとん - folklorecrysisprogrammer/folklorecrisis GitHub Wiki

【拡張有限オートマトン】

有限オートマトン的なのを実装します。(恐らく、決定性有限オートマトン)
状態Aの時1が入力されると状態がBになるオートマトンを定義するなら、
A.setRule(input(1)>>_state(B));
↑このようになります
以下は詳細な解説です。

【ルール書き方】

Rule=input(入力名)>>アクション>>アクション.....
さらに、|を使って複数のRuleを結合できます。
Rule3=
            Rule1 |
            Rule2 |
            input(KFC)>>_state(マクドナルド);

【アクションの型】

アクションの型は、以下の型の関数を返すクラスとする。
遷移時にはこの関数が呼ばれるとする。

/関数の型
ienumerator<bool> (Trigger)

この関数の返り値が
yield return falseまたは yield breakで
終了します。
yield return trueの場合は遷移は遅延され、
この関数は再び呼ばれます。

【Ruleが提供する処理】

/x状態をセットする
/これが呼ばれたら以降のアクションは無視される
setState(x)

/現在の状態を取得する
getState()

/これが呼ばれたら遷移中止。
Cancel()

【標準用意のアクション】

/xフレーム遅延
/遅延してる間に新しい入力があった場合、
/現在の遷移を破棄し、新しい入力の方に切り替える。
/(この遷移破棄は全ての遅延するアクションで起こります)
_lazy(x)

/x状態をセット
/setStateを呼んでるのでこれ以降のアクションは呼ばれない
_state(x)

/現在の状態とxが同じなら、cancel()する
_sameStateCancel(x)

【状態にルールを適応させる】

/定義したルールを状態にセットします
/デフォルト入力は、何も入力されなかった時に入力される値です。省略できます。
/省略した場合本当に何も入力されません。
状態.setRule(ルール,デフォルト入力)

【例】

/ルール定義
moveRule=
     input(前)>>
     _sameStateCancel(前歩行)>>
     _state(前歩行)|
     input(後)>>
     _sameStateCancel(後歩行)>>
     _state(後歩行)|
     input(右)>>
     _sameStateCancel(右歩行)>>
     _state(右歩行)|
     input(左)>>
     _sameStateCancel(左歩行)>>
     _state(左歩行);

/各状態にルール適応
前歩行.setRule( 
                 moveRule|
                 input(止)>>
                 lazy(10)>>
                 _state(前立ち止まり)
              );
後歩行.setRule(moveRule);
左歩行.setRule(moveRule);
右歩行.setRule(moveRule);
public:
	void Run() { sm.SetOrderVector(ov); sm.Run(); }
	Script() :Script::base_type(Code) {
		std::vector<int> v = {1,2,3};
		using boost::phoenix::ref;
		using spt::qi::eps;
		using spt::qi::lit;
		using spt::qi::_1;
		using spt::qi::_val;
		using spt::qi::double_;
		using spt::qi::bool_;
		using spt::qi::int_;
		using spt::qi::alpha;
		using spt::qi::as_string;
		using spt::ascii::char_;
		spt::qi::standard_wide::char_type wchar_;
		using spt::qi::real_parser;
		using spt::qi::strict_real_policies;
		real_parser<double, strict_real_policies<double>> strict_double;
		Code = 
			*(
				(DC >> lit(';')) 
				| 
				(-(Label[AddOrderLabel()]>>lit(' '))>>Order[AddOrder()] >> lit(';'))
				|
				(Comment)
			);
		NullChar = lit("\\0")[_val = '\0'];
		EndLineChar = lit("\\n")[_val='\n'];
		Char = lit('\'') >>(NullChar|EndLineChar|char_)-'\''>> lit('\'');
		Value = strict_double | int_|  Char|bool_;
		ValueAdr = Value[_val = BindValueAdr::Make(sm)] | String[_val=BindStringAdr::Make(sm)];
		DC =
			(Label >> lit(' ') >> lit("idc") >> lit(' ') >> int_%',')[BindDCV::Make<int>(sm)] |
			(Label >> lit(' ') >> lit("ddc") >> lit(' ') >> double_%',')[BindDCV::Make<double>(sm)] |
			(Label >> lit(' ') >> lit("bdc") >> lit(' ') >> bool_%',')[BindDCV::Make<bool>(sm)] |
			(Label >> lit(' ') >> lit("cdc") >> lit(' ') >> Char%',')[BindDCV::Make<char>(sm)]|
			(Label >> lit(' ') >> lit("cdc") >> lit(' ') >> String)[BindDCV::Make<char>(sm)];
		Label =as_string[(+(char_('A', 'Z')))];
		String= lit('"')>>(+((NullChar|EndLineChar|char_|wchar_)-'"'))>> lit('"');
		Comment = lit("/*") >>*((char_|wchar_)-"*/")>> lit("*/");
		LabelAdr = Label[_val = BindLabelAdr::Make(sm)];
		Register =
			lit("ax")[_val = sm.GetAX()] |
			lit("gr1")[_val = sm.GetGR(1)] |
			lit("gr2")[_val = sm.GetGR(2)] |
			lit("gr3")[_val = sm.GetGR(3)] |
			lit("gr4")[_val = sm.GetGR(4)] |
			lit("gr5")[_val = sm.GetGR(5)] |
			lit("gr6")[_val = sm.GetGR(6)] |
			lit("gr7")[_val = sm.GetGR(7)] |
			lit("gr8")[_val = sm.GetGR(8)];
		Adr = LabelAdr | Register|ValueAdr;
		Args1 = (Adr >> lit(' ') >> Adr)[_val = BindArgs1::Make()];
		Args3 = (Adr >> lit(' ') >> Adr >> lit(' ') >> Adr)[_val = BindArgs3::Make()];
		Args4 = (Adr >> lit(' ') >> Adr >> lit(' ') >> Adr >> lit(' ') >> Adr)[_val = BindArgs4::Make()];
		Args5 = (Adr)[_val=BindArgs5::Make()];
		Args = (Args1 | Args3 | Args4 | Args5);
		Order = (PRINT|ADD|LD|LDR|JMP|JMPB|CPAEQ|CPANEQ|INC|PUSH|POP|REF|DREF|CAST);
		JMP = lit("jmp") >> lit(' ') >> Args[_val = BindJMP::Make(sm)];
		JMPB = lit("jmpb") >> lit(' ') >> Args[_val = BindJMPB::Make(sm)];
		PRINT = 
			(lit("iprint") >> lit(' ') >> Args[_val = BindPRINT<int>::Make()])|
			(lit("dprint") >> lit(' ') >> Args[_val = BindPRINT<double>::Make()])|
			(lit("bprint") >> lit(' ') >> Args[_val = BindPRINT<bool>::Make()])|
			(lit("cprint") >> lit(' ') >> Args[_val = BindPRINT<char>::Make()])|
		    (lit("sprint") >> lit(' ') >> Args[_val = BindSPRINT::Make()]);
		LD=
			(lit("ild") >> lit(' ') >> Args[_val = BindLD<int>::Make()]) |
			(lit("dld") >> lit(' ') >> Args[_val = BindLD<double>::Make()]) |
			(lit("bld") >> lit(' ') >> Args[_val = BindLD<bool>::Make()]) |
			(lit("cld") >> lit(' ') >> Args[_val = BindLD<char>::Make()]);
		LDR =
			(lit("ildr") >> lit(' ') >> Args[_val = BindLDR<int>::Make()]) |
			(lit("dldr") >> lit(' ') >> Args[_val = BindLDR<double>::Make()]) |
			(lit("bldr") >> lit(' ') >> Args[_val = BindLDR<bool>::Make()]) |
			(lit("cldr") >> lit(' ') >> Args[_val = BindLDR<char>::Make()]);
		ADD =
			(lit("iadd") >> lit(' ') >> Args[_val = BindADD<int>::Make()]) |
			(lit("dadd") >> lit(' ') >> Args[_val = BindADD<double>::Make()]) |
			(lit("badd") >> lit(' ') >> Args[_val = BindADD<bool>::Make()]) |
			(lit("cadd") >> lit(' ') >> Args[_val = BindADD<char>::Make()]) |
			(lit("padd") >> lit(' ') >> Args[_val = BindADD<char*>::Make()]);
		PUSH =
			(lit("ipush") >> lit(' ') >> Args[_val = BindPUSH<int>::Make(sm)]) |
			(lit("dpush") >> lit(' ') >> Args[_val = BindPUSH<double>::Make(sm)]) |
			(lit("bpush") >> lit(' ') >> Args[_val = BindPUSH<bool>::Make(sm)]) |
			(lit("cpush") >> lit(' ') >> Args[_val = BindPUSH<char>::Make(sm)]);
		POP =
			(lit("ipop") >> lit(' ') >> Args[_val = BindPOP<int>::Make(sm)]) |
			(lit("dpop") >> lit(' ') >> Args[_val = BindPOP<double>::Make(sm)]) |
			(lit("bpop") >> lit(' ') >> Args[_val = BindPOP<bool>::Make(sm)]) |
			(lit("cpop") >> lit(' ') >> Args[_val = BindPOP<char>::Make(sm)]);
		INC =
			(lit("iinc") >> lit(' ') >> Args[_val = BindINC<int>::Make()]) |
			(lit("dinc") >> lit(' ') >> Args[_val = BindINC<double>::Make()]) |
			(lit("binc") >> lit(' ') >> Args[_val = BindINC<bool>::Make()]) |
			(lit("cinc") >> lit(' ') >> Args[_val = BindINC<char>::Make()]);
		CPAEQ =
			(lit("icpaeq") >> lit(' ') >> Args[_val = BindCPAEQ<int>::Make(sm)]) |
			(lit("dcpaeq") >> lit(' ') >> Args[_val = BindCPAEQ<double>::Make(sm)]) |
			(lit("bcpaeq") >> lit(' ') >> Args[_val = BindCPAEQ<bool>::Make(sm)]) |
			(lit("ccpaeq") >> lit(' ') >> Args[_val = BindCPAEQ<char>::Make(sm)]);
		CPANEQ =
			(lit("icpaneq") >> lit(' ') >> Args[_val = BindCPANEQ<int>::Make(sm)]) |
			(lit("dcpaneq") >> lit(' ') >> Args[_val = BindCPANEQ<double>::Make(sm)]) |
			(lit("bcpaneq") >> lit(' ') >> Args[_val = BindCPANEQ<bool>::Make(sm)]) |
			(lit("ccpaneq") >> lit(' ') >> Args[_val = BindCPANEQ<char>::Make(sm)]);
		REF =
			(lit("ref") >> lit(' ') >> Args[_val = BindREF::Make()]);
		DREF =
			(lit("idref") >> lit(' ') >> Args[_val = BindDREF<int>::Make()]) |
			(lit("ddref") >> lit(' ') >> Args[_val = BindDREF<double>::Make()]) |
			(lit("bdref") >> lit(' ') >> Args[_val = BindDREF<bool>::Make()]) |
			(lit("cdref") >> lit(' ') >> Args[_val = BindDREF<char>::Make()]) |
			(lit("pdref") >> lit(' ') >> Args[_val = BindDREF<void*>::Make()]);
		CAST =
			(lit("icastd") >> lit(' ') >> Args[_val = BindCAST<int, double>::Make()]) |
			(lit("dcasti") >> lit(' ') >> Args[_val = BindCAST<double, int>::Make()]) |
			(lit("icastc") >> lit(' ') >> Args[_val = BindCAST<int, char>::Make()]) |
			(lit("ccasti") >> lit(' ') >> Args[_val = BindCAST<char, int>::Make()]) |
			(lit("icastb") >> lit(' ') >> Args[_val = BindCAST<int, bool>::Make()]) |
			(lit("bcasti") >> lit(' ') >> Args[_val = BindCAST<bool, int>::Make()]) |
			(lit("dcastc") >> lit(' ') >> Args[_val = BindCAST<double, char>::Make()]) |
			(lit("ccastd") >> lit(' ') >> Args[_val = BindCAST<char, double>::Make()]) |
			(lit("dcastb") >> lit(' ') >> Args[_val = BindCAST<double, bool>::Make()]) |
			(lit("bcastd") >> lit(' ') >> Args[_val = BindCAST<bool, double>::Make()]) |
			(lit("ccastb") >> lit(' ') >> Args[_val = BindCAST<char, bool>::Make()]) |
			(lit("bcastc") >> lit(' ') >> Args[_val = BindCAST<bool, char>::Make()]);
	}
	//scriptコード全体をまとめる文法
	spt::qi::rule<Iterator>Code;
	//DC 命令
	spt::qi::rule<Iterator>DC;
	//PRINT命令
	spt::qi::rule<Iterator,OrderBase*>PRINT;
	//LD命令
	spt::qi::rule<Iterator, OrderBase*>LD;
	//LDA命令
	spt::qi::rule<Iterator, OrderBase*>LDR;
	//ADD命令
	spt::qi::rule<Iterator, OrderBase*>ADD;
	//INC命令
	spt::qi::rule<Iterator, OrderBase*>INC;
	//PUSH命令
	spt::qi::rule<Iterator, OrderBase*>PUSH;
	//POP命令
	spt::qi::rule<Iterator, OrderBase*>POP;
	//CPAEQ命令
	spt::qi::rule<Iterator, OrderBase*>CPAEQ;
	//CPANEQ命令
	spt::qi::rule<Iterator, OrderBase*>CPANEQ;
	//JMP命令
	spt::qi::rule<Iterator, OrderBase*>JMP;
	//JMPB命令
	spt::qi::rule<Iterator, OrderBase*>JMPB;
	//REF命令
	spt::qi::rule<Iterator, OrderBase*>REF;
	//DREF命令
	spt::qi::rule<Iterator, OrderBase*>DREF;
	//CAST命令
	spt::qi::rule<Iterator, OrderBase*>CAST;
	//実行命令
	spt::qi::rule<Iterator, OrderBase*>Order;
	//ラベル
	spt::qi::rule<Iterator,std::string()>Label;
	//ラベルが指すアドレス
	spt::qi::rule<Iterator, void*>LabelAdr;
	//レジスタのアドレス
	spt::qi::rule<Iterator, void*>Register;
	//アドレス
	spt::qi::rule<Iterator, void*>Adr;
	//Arg<1>
	spt::qi::rule<Iterator, Args<1>()>Args1;
	//Arg<3>
	spt::qi::rule<Iterator, Args<3>()>Args3;
	//Arg<4>
	spt::qi::rule<Iterator, Args<4>()>Args4;
	//Arg<5>
	spt::qi::rule<Iterator, Args<5>()>Args5;
	//Args<...>
	spt::qi::rule<Iterator, VarArgs()>Args;
	//char形式
	spt::qi::rule<Iterator,char()>Char;
	//null文字
	spt::qi::rule<Iterator, char()>NullChar;
	//改行文字
	spt::qi::rule<Iterator, char()>EndLineChar;
	//文字列
	spt::qi::rule<Iterator, std::vector<char>>String;
	//コメント
	spt::qi::rule<Iterator>Comment;
	//即値
	spt::qi::rule<Iterator, VarValue>Value;
	//即値アドレス
	spt::qi::rule<Iterator, void*>ValueAdr;

⚠️ **GitHub.com Fallback** ⚠️