OK、私は非常によく似た要件を持っています。異なる構文の行がたくさんあります。基本的には、スマートカード形式のプロセスで使用するための行とコードを含む行、およびキーと秘密コードの記述子行を示しています。いずれにせよ、「モデル」パターン/アクションは、多くの行を認識して処理するための獣のアプローチだと思います。という名前のアセンブリを開発するために for を
使用しています。このライブラリのコアは、基本的に を含む lex_rule クラスです。C++/CLI
LanguageProcessor.dll
DynamicMethod
コンストラクターは正規表現文字列をロードし、Emit
を使用してオンザフライでイベントを構築するために必要なコードを呼び出しますReflexion
。また、アセンブリには、メタやオブジェクトなどの他のクラスが存在し、パブリッシャーの単純な名前でオブジェクトをインスタンス化して構築します。受信者クラス、受信者クラスは、一致した各ルールのアクション ハンドラーを提供します。
遅れて
、配列から定義をロードして実行するfasterlex_engine
Dictionary を構築するという名前のクラスがあります。<Regex, action_delegate>
プロジェクトは進んでいますが、今日もまだ構築中です。次のような正規表現を使用して辞書を直接検索するメカニズムを使用して、すべてのペアの foreach 行入力への順次アクセスを囲む実行のパフォーマンスを向上させようとします。
map_rule[gcnew Regex("[a-zA-Z]")];
ここに、私のコードのいくつかのセグメントがあります:
public ref class lex_rule: ILexRule
{
private:
Exception ^m_exception;
Regex ^m_pattern;
//BACKSTORAGE delegates, esto me lo aprendi asiendo la huella.net de m*e*da JEJE
yy_lexical_action ^m_yy_lexical_action;
yy_user_action ^m_yy_user_action;
public:
virtual property String ^short_id;
private:
void init(String ^_short_id, String ^well_formed_regex);
public:
lex_rule();
lex_rule(String ^_short_id,String ^well_formed_regex);
virtual event yy_lexical_action ^YY_RULE_MATCHED
{
virtual void add(yy_lexical_action ^_delegateHandle)
{
if(nullptr==m_yy_lexical_action)
m_yy_lexical_action=_delegateHandle;
}
virtual void remove(yy_lexical_action ^)
{
m_yy_lexical_action=nullptr;
}
virtual long raise(String ^id_rule, String ^input_string, String ^match_string, int index)
{
long lReturn=-1L;
if(m_yy_lexical_action)
lReturn=m_yy_lexical_action(id_rule,input_string, match_string, index);
return lReturn;
}
}
};
多くのパターン/アクションのペアを実行する高速なlex_engineクラス:
public ref class fasterlex_engine
{
private:
Dictionary<String^,ILexRule^> ^m_map_rules;
public:
fasterlex_engine();
fasterlex_engine(array<String ^,2>^defs);
Dictionary<String ^,Exception ^> ^load_definitions(array<String ^,2> ^defs);
void run();
};
そして、このトピックを飾るために..私のcppファイルのいくつかのコード:
このコードは、パラメーター サインによってコンストラクター呼び出し元を作成します
inline Exception ^object::builder(ConstructorInfo ^target, array<Type^> ^args)
{
try
{
DynamicMethod ^dm=gcnew DynamicMethod(
"dyna_method_by_totem_motorist",
Object::typeid,
args,
target->DeclaringType);
ILGenerator ^il=dm->GetILGenerator();
il->Emit(OpCodes::Ldarg_0);
il->Emit(OpCodes::Call,Object::typeid->GetConstructor(Type::EmptyTypes)); //invoca a constructor base
il->Emit(OpCodes::Ldarg_0);
il->Emit(OpCodes::Ldarg_1);
il->Emit(OpCodes::Newobj, target); //NewObj crea el objeto e invoca al constructor definido en target
il->Emit(OpCodes::Ret);
method_handler=(method_invoker ^) dm->CreateDelegate(method_invoker::typeid);
}
catch (Exception ^e)
{
return e;
}
return nullptr;
}
このコードは、入力文字列の一致によって発生したコールバックを処理するために、任意のハンドラー関数 (静的または非静的) をアタッチします。
Delegate ^connection_point::hook(String ^receiver_namespace,String ^receiver_class_name, String ^handler_name)
{
Delegate ^d=nullptr;
if(connection_point::waitfor_hook<=m_state) // si es 0,1,2 o mas => intenta hookear
{
try
{
Type ^tmp=meta::_class(receiver_namespace+"."+receiver_class_name);
m_handler=tmp->GetMethod(handler_name);
m_receiver_object=Activator::CreateInstance(tmp,false);
d=m_handler->IsStatic?
Delegate::CreateDelegate(m_tdelegate,m_handler):
Delegate::CreateDelegate(m_tdelegate,m_receiver_object,m_handler);
m_add_handler=m_connection_point->GetAddMethod();
array<Object^> ^add_handler_args={d};
m_add_handler->Invoke(m_publisher_object, add_handler_args);
++m_state;
m_exception_flag=false;
}
catch(Exception ^e)
{
m_exception_flag=true;
throw gcnew Exception(e->ToString()) ;
}
}
return d;
}
最後に、レクサーエンジンを呼び出すコード:
array<String ^,2> ^defs=gcnew array<String^,2> {/* shortID pattern namespc clase fun*/
{"LETRAS", "[A-Za-z]+" ,"prueba", "manejador", "procesa_directriz"},
{"INTS", "[0-9]+" ,"prueba", "manejador", "procesa_comentario"},
{"REM", "--[^\\n]*" ,"prueba", "manejador", "nullptr"}
}; //[3,5]
//USO EL IDENTIFICADOR ESPECIAL "nullptr" para que el sistema asigne el proceso del evento a un default que realice nada
fasterlex_engine ^lex=gcnew fasterlex_engine();
Dictionary<String ^,Exception ^> ^map_error_list=lex->load_definitions(defs);
lex->run();