本家「@IT」にはない内容をエンジニアライフで技術紹介するコラム。広く議論する場になることを目指します。

第035回_Visitorの機能拡張3

»
今回は、
 応用トークンの処理:ExtendTokenSyntaxParserVisitor
 AttValue構文の処理:NotifyAttValueVisitor
 EntityValue構文の処理:NotifyEntityValueVisitor
 構文確認のためのVisitor:SyntaxParserVisitor
を作成します。

ExtendTokenSyntaxParserVisitorの検討と実装

検討
XMLの応用ノードとトークンは、字句解析器の実装から
ノード:トークン
――――――――――――――――――――――
EbnfNormalTokenA1Node:NormalTokenA1
EbnfNormalTokenA2Node:NormalTokenA2
EbnfNormalTokenB1Node:NormalTokenB1
EbnfNormalTokenB2Node:NormalTokenB2
とします。

実装

public abstract class ExtendTokenSyntaxParserVisitor
                      extends XmlTokenSyntaxParserVisitor
{
    public ExtendTokenSyntaxParserVisitor()
    {
        super();
    }

    @Override
    public void visit(EbnfNormalTokenA1Node n)
    {
        Token token = m_tokenManager.nextToken();
        m_result = token.match(n);
    }

    @Override
    public void visit(EbnfNormalTokenA2Node n)
    {
        Token token = m_tokenManager.nextToken();
        m_result = token.match(n);
    }
    
    @Override
    public void visit(EbnfNormalTokenB1Node n)
    {
        Token token = m_tokenManager.nextToken();
        m_result = token.match(n);
    }

    @Override
    public void visit(EbnfNormalTokenB2Node n)
    {
        Token token = m_tokenManager.nextToken();
        m_result = token.match(n);
    }
}
EbnfNormalTokenA1Node, EbnfNormalTokenA2Node, EbnfNormalTokenB1Node, EbnfNormalTokenB2Nodeの実装は文字列パターンのない処理として実装します。(割愛)

NotifyAttValueVisitorの実装

AttValueに関連するVisitorの実装をします。AttValueの構文は今後、このクラス自体を拡張するのに備えて他のクラスとは分けて実装します。

public abstract class NotifyAttValueVisitor
                extends ExtendTokenSyntaxParserVisitor
{
    public NotifyAttValueVisitor()
    {
        super();
    }

    public void visit(EbnfAttValueQuoteStartNode n)
    {
        m_tokenManager.notifyQuoteStart();
        this.visit((EbnfSymbolNode)n);
        m_tokenManager.notifyQuoteEnd();
    }
    
    public void visit(EbnfAttValueDoubleQuoteStartNode n)
    {
        m_tokenManager.notifyDoubleQuoteStart();
        this.visit((EbnfSymbolNode)n);
        m_tokenManager.notifyDoubleQuoteEnd();
    }
    
    public void visit(EbnfAttValueQuoteSectionNode n)
    {
        m_tokenManager.notifyAttValueQuoteSectionStart();
        this.visit((EbnfSequenceNode)n);
        m_tokenManager.notifyAttValueQuoteSectionEnd();
    }
    
    public void visit(EbnfAttValueDoubleQuoteSectionNode n)
    {
        m_tokenManager.notifyAttValueDoubleQuoteSectionStart();
        this.visit((EbnfSequenceNode)n);
        m_tokenManager.notifyAttValueDoubleQuoteSectionEnd();
    }

    @Override
    public void visit(EbnfAvHexCharRefSectionNode n)
    {
        m_tokenManager.notifyNormalSectionStart();
        this.visit((EbnfSequenceNode)n);
        m_tokenManager.notifyNormalSectionEnd();
    }

    @Override
    public void visit(EbnfAvDecimalCharRefSectionNode n)
    {
        m_tokenManager.notifyNormalSectionStart();
        this.visit((EbnfSequenceNode)n);
        m_tokenManager.notifyNormalSectionEnd();
    }

    @Override
    public void visit(EbnfAvEntityRefSectionNode n)
    {
        m_tokenManager.notifyNormalSectionStart();
        this.visit((EbnfSequenceNode)n);
        m_tokenManager.notifyNormalSectionEnd();
    }
}

NotifyEntityValueVisitorの実装

EntityValueに関連するVisitorの実装をします。AttValueの構文と同じく、今後このクラス自体を拡張するのに備えて他のクラスとは分けて実装します。

public abstract class NotifyEntityValueVisitor extends NotifyAttValueVisitor
{
    public NotifyEntityValueVisitor()
    {
        super();
    }

    @Override
    public void visit(EbnfEntityValueQuoteStartNode n)
    {
        m_tokenManager.notifyQuoteStart();
        this.visit((EbnfSymbolNode)n);
        m_tokenManager.notifyQuoteEnd();
    }

    @Override
    public void visit(EbnfEntityValueDoubleQuoteStartNode n)
    {
        m_tokenManager.notifyDoubleQuoteStart();
        this.visit((EbnfSymbolNode)n);
        m_tokenManager.notifyDoubleQuoteEnd();
    }

    @Override
    public void visit(EbnfEntityValueQuoteSectionNode n)
    {
        m_tokenManager.notifyEntityValueQuoteSectionStart();
        this.visit((EbnfSequenceNode)n);
        m_tokenManager.notifyEntityValueQuoteSectionEnd();
    }

    @Override
    public void visit(EbnfEntityValueDoubleQuoteSectionNode n)
    {
        m_tokenManager.notifyEntityValueDoubleQuoteSectionStart();
        this.visit((EbnfSequenceNode)n);
        m_tokenManager.notifyEntityValueDoubleQuoteSectionEnd();
    }
    
    @Override
    public void visit(EbnfGeDecimalCharRefSectionNode n)
    {
        m_tokenManager.notifyNormalSectionStart();
        this.visit((EbnfSequenceNode)n);
        m_tokenManager.notifyNormalSectionEnd();
    }
    
    @Override
    public void visit(EbnfEntityRefSectionNode n)
    {
        m_tokenManager.notifyNormalSectionStart();
        this.visit((EbnfSequenceNode)n);
        m_tokenManager.notifyNormalSectionEnd();
    }

    @Override
    public void visit(EbnfGeHexCharRefSectionNode n)
    {
        m_tokenManager.notifyNormalSectionStart();
        this.visit((EbnfSequenceNode)n);
        m_tokenManager.notifyNormalSectionEnd();
    }

    @Override
    public void visit(EbnfGePEReferenceSectionNode n)
    {
        m_tokenManager.notifyNormalSectionStart();
        this.visit((EbnfSequenceNode)n);
        m_tokenManager.notifyNormalSectionEnd();
    }
}

SyntaxParserVisitorの実装

SyntaxParserVisitorは構文が合致してるかのみを確認するVisitorです。

もし、XMLファイルを読み込んでデータ生成をしたい場合はSyntaxParserVisitorを継承したクラスを利用します。

また、これまでに未登場のノードクラスをEbnfVisitorに追加した場合は、SyntaxParserVisitorにそのノードクラス用のVisitが必要になります。


public class SyntaxParserVisitor extends NotifyEntityValueVisitor
{
    public SyntaxParserVisitor()
    {
        super();
    }
}
これでXMLを構文解析する準備ができました。次回は、アプリケーションとして動かすために必要なモジュールを作成します。
Comment(0)

コメント

コメントを投稿する