ç¶æ é·ç§»è¡¨ãä½æãã
ããµã³ãã«ã¨ãã¦
ãã½ã¼ã¹ã³ã¼ãï¼ããã¹ããã¡ã¤ã«ï¼ãã ãããã¯ã³ã¡ã³ã:/*ãã*/ã¾ã§ 㨠ã©ã¤ã³ã³ã¡ã³ã://ããæ¹è¡ã¾ã§ ãæ½åºãåºåããã
ãä¸ããããè¦ä»¶ï¼è¦æ±ã¨ãã¾ãã
ããã®è¦æ±ãç¶æ é·ç§»ã§å®ç¾ããã«ãããæãã¤ãç¶æ ã¨ãã¦ã¯ã"ã³ã¡ã³ãã®å¤","ãããã¯ã³ã¡ã³ãã®ä¸","ã©ã¤ã³ã³ã¡ã³ãã®ä¸"â¦â¦ã»ãã«ã'/'ã®ç´å¾ã¯ã³ã¡ã³ãã®ä¸ãå¤ãå®ã¾ã£ã¦ããªãã®ã§"/ã®ç´å¾"ãªãã¦ç¶æ ãå¿ è¦ã«ãªãããã§ãã
ãããã¦ã¤ãã³ãã¯ãã¡ã¤ã«ãã'/','*',æ¹è¡,ãã®ä» ã®åæåãèªã¿è¾¼ãã ãã®4種ã§ããããªã
ãããªã³ã¿ç¨ç´ã«éçã§ä¸¸ã¨ç¢å°ãæãã¦ã¯æ¶ãã¦ã§ãããã£ãç¶æ é·ç§»å³ãã³ã¬ã
ãç¶æ é·ç§»å³ãåºã«ãé·ç§»ã«ä¼´ãã¢ã¯ã·ã§ã³ãå ãã¦è»¢è¨ããç¶æ é·ç§»è¡¨ãã³ã¬ã§ãã
ç¶æ é·ç§»è¡¨ããã²ãªåã³ã¼ããçæãã
ããã®ç¶æ é·ç§»è¡¨ããã³ã¼ããèµ·ããããã§ãããç¶æ é·ç§»ã®å®è£ ã«ã¤ãã¦ã¯ãStateãã¿ã¼ã³ã§CSVãèªãããæ¸ãã¾ããããã¶ã¤ã³ã»ãã¿ã¼ã³ã®ä¸ã¤:Stateã«ããå®è£ ã§ããä»åã®å®è£ ã¯Cãç¶æ¿ãä»®æ³é¢æ°ã使ããªãã¨ããå©ãè ãå°ããããæ¡ä»¶ãªã®ã§æ¦è¡ã大ããå¤ãã«ããªããã§ãã
ãç¶æ é·ç§»ã®å®è£ ã¯è¦ããã«ãï¼1ï¼ç¾ç¶æ 㨠ï¼2ï¼åçããã¤ãã³ã ã®çµãã«å¯¾å¿ãããï¼3ï¼ã¢ã¯ã·ã§ã³ 㨠ï¼4ï¼é·ç§»å ï¼æ°ããªç¶æ ï¼ããå¼ãå½ã¦ããã¨ã«ä»ãªãã¾ããããªãã°ä¸è¨ï¼1ï¼ï½ï¼4ï¼ã®ä¸¦ã³ãã¬ã³ã¼ãã¨ãããã®ã¬ã³ã¼ãåï¼ï¼ç¶æ é·ç§»è¡¨ï¼ãããï¼1ï¼ç¾ç¶æ 㨠ï¼2ï¼åçããã¤ãã³ã ã®çµãã«ä¸è´ããã¬ã³ã¼ããæ¢ãåºãã¦ãï¼3ï¼ã¢ã¯ã·ã§ã³ ãå®è¡ã㦠ï¼4ï¼æ°ããªç¶æ ã«é·ç§»ãããã°ããã
ãç¶æ é·ç§»è¡¨ããã²ãªåã³ã¼ãã®çæã«ã¯ä½¿ãæ £ãããT4-templateããç¨ãã¾ãããã³ãã¬ã¼ãã«è¨è¿°ããã®ã¯ enum S { ç¶æ ... } 㨠enum E { ã¤ãã³ã... } ããã¦ç¶æ é·ç§»è¡¨: transition(ç¶æ ,ã¤ãã³ã,é·ç§»å ...) ã並ã¹ããã®ã§ããã¢ã¯ã·ã§ã³ã¯ç¶æ ã¨ã¤ãã³ãããé©å½ãªååãä¸ããé¢æ°ï¼å½ç¶ä¸èº«ããã£ã½ï¼ãåããã¾ããé·ç§»å ã¯è¤æ°åï¼4ã¤ã¾ã§ï¼æ¸ããããã«ãã¾ãããã¨ããã®ããå®éã®è¨è¨ã§ã¯ã¢ã¯ã·ã§ã³ã®çµæ次第ã§é·ç§»å ãç°ãªãã±ã¼ã¹ãã¾ã¾ããã®ã§ããä¾ãã°ãåæç¶æ ã§éå§ã¤ãã³ããããããã£ãã«ããªã¼ãã³ãã¦åä¿¡å¾ ã¡ã«é·ç§»ãããå ´åããã£ãã«ã®ãªã¼ãã³ã«å¤±æãããåæç¶æ ã«æ»ãããããããªã±ã¼ã¹ã«å¯¾å¿ãã¹ããã¢ã¯ã·ã§ã³ãè¿ããå¤nã«å¿ãã¦é·ç§»å ãã®nãæå®ã§ããããã«ã
ãã³ã¡ã³ãæ½åºï¼ExtractCommentï¼ãè¡ãç¶æ é·ç§»è¡¨ãã³ãã¬ã¼ã:state_transition.ttã¯ãããªãã¤ã§ãã
<#@ output encoding="shift_jis" #> <#@ template debug="false" hostspecific="true" language="C#" #> <# string prefix = this.Host.ResolveParameterValue("","","prefix"); int slen = 0; foreach( string s in Enum.GetNames(typeof(S)) ) if ( slen < s.Length ) slen = s.Length; int elen = 0; foreach( string e in Enum.GetNames(typeof(E)) ) if ( elen < e.Length ) elen = e.Length; #> <#@ include file="state_transition_.tt" #> <#+ static Tuple<S,E,S[]> transition(S s, E e, params S[] n) { return Tuple.Create(s,e,n); } // ç¶æ ãåæ enum S { OUT_COMMENT, SECOND_LEAD, IN_BLOCKCOMMENT, IN_LINECOMMENT, SECOND_TRAIL, }; // ã¤ãã³ããåæ enum E { STAR, SLASH, LF, OTHER }; // 以ä¸ã«æ¸ãããç¶æ é·ç§»è¡¨ã«åºã¥ãã¦ã³ã¼ããçæãã Tuple<S,E,S[]>[] _transition_ = { // ç¶æ , ã¤ãã³ã,次ã®ç¶æ ... transition(S.OUT_COMMENT, E.STAR, S.OUT_COMMENT), transition(S.OUT_COMMENT, E.SLASH, S.SECOND_LEAD), transition(S.OUT_COMMENT, E.LF, S.OUT_COMMENT), transition(S.OUT_COMMENT, E.OTHER, S.OUT_COMMENT), transition(S.SECOND_LEAD, E.STAR, S.IN_BLOCKCOMMENT), transition(S.SECOND_LEAD, E.SLASH, S.IN_BLOCKCOMMENT), transition(S.SECOND_LEAD, E.LF, S.OUT_COMMENT), transition(S.SECOND_LEAD, E.OTHER, S.OUT_COMMENT), transition(S.IN_BLOCKCOMMENT, E.STAR, S.SECOND_TRAIL), transition(S.IN_BLOCKCOMMENT, E.SLASH, S.IN_BLOCKCOMMENT), transition(S.IN_BLOCKCOMMENT, E.LF, S.IN_BLOCKCOMMENT), transition(S.IN_BLOCKCOMMENT, E.OTHER, S.IN_BLOCKCOMMENT), transition(S.IN_LINECOMMENT, E.STAR, S.IN_LINECOMMENT), transition(S.IN_LINECOMMENT, E.SLASH, S.IN_LINECOMMENT), transition(S.IN_LINECOMMENT, E.LF, S.OUT_COMMENT), transition(S.IN_LINECOMMENT, E.OTHER, S.IN_LINECOMMENT), transition(S.SECOND_TRAIL, E.STAR, S.SECOND_TRAIL), transition(S.SECOND_TRAIL, E.SLASH, S.OUT_COMMENT), transition(S.SECOND_TRAIL, E.LF, S.IN_BLOCKCOMMENT), transition(S.SECOND_TRAIL, E.OTHER, S.IN_BLOCKCOMMENT), }; #>
ããµã³ãã«ãã¡ã¤ã«ã®ãã£ã¬ã¯ããª:state_transitonã«ä¸è¨ãã³ãã¬ã¼ãã¨çæããã:state_transiton.batãç¨æãã¾ãããã³ãã³ãã©ã¤ã³ãã state_transition ec ããã¨ãã²ãªåã³ã¼ã:ec_state_transition.h/.c ãçæããã¾ããCã¯åå空éãæããªãã®ã§ã·ã³ãã«ã®è¡çªåé¿ã®ãããã¬ãã£ã¯ã¹ï¼ããã§ã¯ecï¼ãä»ããããããã«ãã¾ããã
#ifndef EC_STATE_TRANSITION_H_ #define EC_STATE_TRANSITION_H_ /* ----------------------------------------------------- * ç¶æ é·ç§» ec * ----------------------------------------------------- */ #include <stdbool.h> /* from C99 : defines bool, true, false */ #include "statemachine_defs.h" /* * ç¶æ ãåæ */ enum ec_state_code_t { EC_S_OUT_COMMENT, EC_S_SECOND_LEAD, EC_S_IN_BLOCKCOMMENT, EC_S_IN_LINECOMMENT, EC_S_SECOND_TRAIL, }; typedef enum ec_state_code_t ec_state_code; /* * ã¤ãã³ããåæ */ enum ec_event_code_t { EC_E_STAR, EC_E_SLASH, EC_E_LF, EC_E_OTHER, }; typedef enum ec_event_code_t ec_event_code; /* * ã¤ãã³ãããã³ä»éãããã¼ã¿ */ struct ec_event_t { ec_event_code event_code_; /* your ftuff here */ }; typedef struct ec_event_t ec_event; /* * ã¢ã¯ã·ã§ã³ã®å®è¡ã«å¿ è¦ãªãã¼ã¿ */ struct ec_context_t { int dummy; /* you may remove this */ /* your stuff here */ }; typedef struct ec_context_t ec_context; /* ---------------- */ #ifdef __cplusplus extern "C" { #endif event_code ec_event_get_event_code(const event* ev); void ec_event_set_event_code(event* ev, event_code evc); void ec_event_make(ec_event* ev, void* arg, ec_state_code st); bool ec_context_setup(ec_context* ctx, void* arg); void ec_context_teardown(ec_context* ctx); transition* ec_state_transition_table(void); const char* ec_state_code_to_c_str(state_code st); const char* ec_event_code_to_c_str(event_code ev); #ifdef __cplusplus } #endif #endif
#include <assert.h> #include <stddef.h> #include "ec_state_transition.h" /* ----------------------- * state * ----------------------- */ // stcã«å¯¾å¿ããæååãè¿ã const char* ec_state_code_to_c_str(state_code stc) { const char* result; switch ( stc ) { case EC_S_OUT_COMMENT : result = "EC_S_OUT_COMMENT"; break; case EC_S_SECOND_LEAD : result = "EC_S_SECOND_LEAD"; break; case EC_S_IN_BLOCKCOMMENT : result = "EC_S_IN_BLOCKCOMMENT"; break; case EC_S_IN_LINECOMMENT : result = "EC_S_IN_LINECOMMENT"; break; case EC_S_SECOND_TRAIL : result = "EC_S_SECOND_TRAIL"; break; default : result = "ec_S_BAD_STATE"; break; } return result; } /* ----------------------- * event * ----------------------- */ // evå ã®event_codeãè¿ã event_code ec_event_get_event_code(const event* ev) { return ((const ec_event*)ev)->event_code_; } // evå ã«event_codeãè¨å®ãã void ec_event_set_event_code(event* ev, event_code evc) { ((ec_event*)ev)->event_code_ = evc; } // event_codeã«å¯¾å¿ããæååãè¿ã const char* ec_event_code_to_c_str(event_code ev) { const char* result; switch ( ev ) { case EC_E_STAR : result = "EC_E_STAR"; break; case EC_E_SLASH : result = "EC_E_SLASH"; break; case EC_E_LF : result = "EC_E_LF"; break; case EC_E_OTHER : result = "EC_E_OTHER"; break; default : result = "EC_E_BAD_EVENT"; break; } return result; } // argããã³stãåºã«ãevå ã«event_codeããã³ä»å¸¯æ å ±ãè¨å®ãã void ec_event_make(ec_event* ev, void* arg, ec_state_code st) { /* your stuff here */ } /* ----------------------- * context * ----------------------- */ // contextãåæåãããæå/失ææã«true/falseãè¿ãã bool ec_context_setup(ec_context* ctx, void* arg) { /* your stuff here */ return true; } // contextã解ä½ããã void ec_context_teardown(ec_context* ctx) { /* do nothing */ } /* ----------------------- * action * ----------------------- */ /* ec action for state:OUT_COMMENT event:STAR */ static int ec_action_S0_E0(const event* ev, context* ctx) { int result = 0; #ifndef STATEMACHINE_TEST /* your stuff here */ #endif return result; } ... ä¸ç¥ ... /* ----------------------- * state_transition_table * ----------------------- */ transition* ec_state_transition_table(void) { static transition table[] = { { EC_S_OUT_COMMENT , EC_E_STAR , &ec_action_S0_E0, { EC_S_OUT_COMMENT, }}, { EC_S_OUT_COMMENT , EC_E_SLASH, &ec_action_S0_E1, { EC_S_SECOND_LEAD, }}, { EC_S_OUT_COMMENT , EC_E_LF , &ec_action_S0_E2, { EC_S_OUT_COMMENT, }}, { EC_S_OUT_COMMENT , EC_E_OTHER, &ec_action_S0_E3, { EC_S_OUT_COMMENT, }}, { EC_S_SECOND_LEAD , EC_E_STAR , &ec_action_S1_E0, { EC_S_IN_BLOCKCOMMENT, }}, { EC_S_SECOND_LEAD , EC_E_SLASH, &ec_action_S1_E1, { EC_S_IN_BLOCKCOMMENT, }}, { EC_S_SECOND_LEAD , EC_E_LF , &ec_action_S1_E2, { EC_S_OUT_COMMENT, }}, { EC_S_SECOND_LEAD , EC_E_OTHER, &ec_action_S1_E3, { EC_S_OUT_COMMENT, }}, { EC_S_IN_BLOCKCOMMENT, EC_E_STAR , &ec_action_S2_E0, { EC_S_SECOND_TRAIL, }}, { EC_S_IN_BLOCKCOMMENT, EC_E_SLASH, &ec_action_S2_E1, { EC_S_IN_BLOCKCOMMENT, }}, { EC_S_IN_BLOCKCOMMENT, EC_E_LF , &ec_action_S2_E2, { EC_S_IN_BLOCKCOMMENT, }}, { EC_S_IN_BLOCKCOMMENT, EC_E_OTHER, &ec_action_S2_E3, { EC_S_IN_BLOCKCOMMENT, }}, { EC_S_IN_LINECOMMENT , EC_E_STAR , &ec_action_S3_E0, { EC_S_IN_LINECOMMENT, }}, { EC_S_IN_LINECOMMENT , EC_E_SLASH, &ec_action_S3_E1, { EC_S_IN_LINECOMMENT, }}, { EC_S_IN_LINECOMMENT , EC_E_LF , &ec_action_S3_E2, { EC_S_OUT_COMMENT, }}, { EC_S_IN_LINECOMMENT , EC_E_OTHER, &ec_action_S3_E3, { EC_S_IN_LINECOMMENT, }}, { EC_S_SECOND_TRAIL , EC_E_STAR , &ec_action_S4_E0, { EC_S_SECOND_TRAIL, }}, { EC_S_SECOND_TRAIL , EC_E_SLASH, &ec_action_S4_E1, { EC_S_OUT_COMMENT, }}, { EC_S_SECOND_TRAIL , EC_E_LF , &ec_action_S4_E2, { EC_S_IN_BLOCKCOMMENT, }}, { EC_S_SECOND_TRAIL , EC_E_OTHER, &ec_action_S4_E3, { EC_S_IN_BLOCKCOMMENT, }}, { -1, -1, NULL, { -1 }} /* DO NOT FORGET THIS TERMINATOR! */ }; return table; }