第060回_一般実体テーブル作成処理の実装4
»
前回の続きで、検討したVisitorを実装します。
ExternalIDの実装
ExternalIDのデータ構造を持つクラスExternalIDクラスの実装は次にようにします。public class ExternalID
{
//systemLiteral部分
private String m_systemLiteral;
//pubidLiteral部分
private String m_pubidLiteral;
public ExternalID()
{
m_systemLiteral = "";
m_pubidLiteral = "";
}
public boolean isEmpty()
{
return m_systemLiteral.isEmpty() && m_pubidLiteral.isEmpty();
}
public void setSystemLiteral(String str)
{
m_systemLiteral = StringController.trimAChar(str);
}
public void setPubidLiteral(String str)
{
m_pubidLiteral = StringController.trimAChar(str);
}
}
StringControllerの実装
StringControllerはXMLパーサが要求する文字列の制御をするクラスです。LiteralTokenの文字列は両端の"や'を含みますが、PubidLiteralやSystemLiteral以降、内部で保持するためには不要になるので削除します。
実装は次のようにできます。
public class StringController
{
//状態をもたず、staticメソッドだけを持つため
//コンストラクタはprivateで呼び出せないようにする
private StringController(){}
//先頭と末尾の""や''を取り除く
public static String trimAChar(String literal)
{
return literal.substring(1, literal.length()-1);
}
}
ExternalIDVisitorの実装
ExternalIDのデータ構造を構築するためのVisitor。ExternalIDVisitorの実装は次のようになります。
public class ExternalIDVisitor extends SyntaxParserVisitor
{
private ExternalID m_externalId;
public ExternalIDVisitor()
{
m_externalId = new ExternalID();
}
public ExternalID getExternalId()
{
return m_externalId;
}
@Override
public void visit(EbnfPubidLiteralNode n)
{
Token token = m_tokenManager.nextToken();
m_result = token.match(n);
if (m_result)
{
String str = token.getString();
m_externalId.setPubidLiteral(str);
}
else
{
//何もしない
}
}
@Override
public void visit(EbnfSystemLiteralNode n)
{
Token token = m_tokenManager.nextToken();
m_result = token.match(n);
if (m_result)
{
String str = token.getString();
m_externalId.setSystemLiteral(str);
}
else
{
//何もしない
}
}
}
MakingGeTableVisitorの実装
これまでの子ノード向けのVisitorを使ってGEDeclを解析して、一般実体のシンボルテーブルを作成するVisitorを用意します。実装は次のようにできます。
public class MakingGeTableVisitor extends SyntaxParserVisitor
{
//実体のシンボルテーブル
private static EntityTable m_table
= EntityTable.getInstance();
//巡回データName部分
private String m_name;
//巡回データNDataName部分
private String m_nDataName;
//巡回データExternalID部分
private ExternalID m_externalId;
private GeneralEntityData m_ged;
public MakingGeTableVisitor()
{
m_name = "";
m_nDataName = null;
m_ged = null;
}
@Override
public void visit(EbnfGEDeclNode n)
{
super.visit(n);
if(m_result)
{
//テーブルに追加する
m_table.setData(m_ged);
}
else
{
//何もしない
}
}
@Override
public void visit(EbnfGeNameNode n)
{
Token token = m_tokenManager.nextToken();
m_result = token.match(n);
if(m_result)
{
//処理に成功したので巡回用データに登録する
m_name = token.getString();
}
else
{
//何もしない
}
}
@Override
public void visit(EbnfGeEntityValueNode n)
{
EntityValueVisitor v = new EntityValueVisitor();
v.visit(n);
m_result = v.getResult();
if (m_result)
{
//一般実体のデータを作成し、巡回データに設定する
InternalParsedEntityData data
= new InternalParsedEntityData();
//既に巡回済みのEbnfGeNameNodeの値を設定する
data.setName(m_name);
String value = v.getValue();
data.setText(value);
m_ged = data;
}
else
{
//何もしない
}
}
@Override
public void visit(EbnfExternalDefNode n)
{
//子ノードを巡回処理する
super.visit(n);
//NDataDefがないとき
if (m_nDataName.equals(""))
{
//外部解析対象実体を作成する
ExternalParsedEntityData data
= new ExternalParsedEntityData();
data.setName(m_name);
data.setExternalId(m_externalId);
m_ged = data;
}
//NDataDefがあるとき
else
{
//解析対象外実体を作成する
ExternalUnparsedEntityData data
= new ExternalUnparsedEntityData();
data.setName(m_name);
data.setExternalId(m_externalId);
data.setNDataName(m_nDataName);
m_ged = data;
}
}
@Override
public void visit(EbnfGeExternalIDNode n)
{
ExternalIDVisitor v = new ExternalIDVisitor();
n.accept(v);
m_result = v.getResult();
if (m_result)
{
m_externalId = v.getExternalId();
}
}
@Override
public void visit(EbnfNDataNameNode n)
{
Token token = m_tokenManager.nextToken();
m_result = token.match(n);
if(m_result)
{
//処理に成功したので巡回用データに登録する
m_nDataName = token.getString();
}
else
{
//何もしない
}
}
}
DoctypedeclVisitorの修正
MakingGeTableVisitorを実行するために、親構文のDoctypedeclVisitorを修整します。public class DoctypedeclVisitor extends SyntaxParserVisitor
{
@Override
public void visit(EbnfGEDeclNode n)
{
MakingEntitySymbolTableVisitor v = new MakingEntitySymbolTableVisitor();
n.accept(v);
}
}
コメント
コメントを投稿する
SpecialPR