第034回_Visitorの機能拡張2
														» 
													
												
前回の続きでEbnfVisitorに解析用の子クラスを作成していきます。
前回は、基本のパーサ用クラスの処理:BaseSyntaxParserVisitorを作成しました。
今回は、基本トークン用クラスの処理:BaseTokenSyntaxParserVisitorとXMLトークン用クラスの処理:XmlTokenSyntaxParserVisitor
を作成します。基本トークンとXMLトークンを分けたのは、他のパーサに転用するときにメンテナンスを楽にするためです。
PIWordToken、CharDataToken、CDataToken、IgnoreWordTokenの実装は文字列パターンのない処理として実装します。(割愛)
														
														
														
														
                                                    	
													
												前回は、基本のパーサ用クラスの処理:BaseSyntaxParserVisitorを作成しました。
今回は、基本トークン用クラスの処理:BaseTokenSyntaxParserVisitorとXMLトークン用クラスの処理:XmlTokenSyntaxParserVisitor
を作成します。基本トークンとXMLトークンを分けたのは、他のパーサに転用するときにメンテナンスを楽にするためです。
BaseTokenSyntaxParserVisitorの検討と実装
■検討
■Tokenの実装
XMLの基本ノードとトークンは、字句解析器の実装から
とします。
■Visitorの実装| ノード | : | トークン | 
| ―――――――――――――――――――――― | ||
| EbnfCommentNode | : | CommentToken | 
| EbnfSymbolNode | : | SymbolToken | 
| EbnfWhiteSpaceNode | : | WhiteSpaceToken | 
| EbnfLimitedWordNode | : | WordToken | 
| EbnfLimitedLiteralNode | : | LiteralToken | 
public abstract class BaseTokenSyntaxParserVisitor
                      extends BaseSyntaxParserVisitor
{
    public BaseTokenSyntaxParserVisitor()
    {
        super();
    }
    @Override
    public void visit(EbnfCommentNode n)
    {
        Token token = m_tokenManager.nextToken();
        m_result = token.match(n);
    }
    @Override
    public void visit(EbnfSymbolNode n)
    {
        Token token = m_tokenManager.nextToken();
        m_result = token.match(n);
    }
    @Override
    public void visit(EbnfWhiteSpaceNode n)
    {
        Token token = m_tokenManager.nextToken();
        m_result = token.match(n);
    }
    @Override
    public void visit(EbnfLimitedWordNode n)
    {
        Token token = m_tokenManager.nextToken();
        m_result = token.match(n);
    }
    
    
    @Override
    public void visit(EbnfLimitedLiteralNode n)
    {
        Token token = m_tokenManager.nextToken();
        m_result = token.match(n);
    }
}
文字列パターンがない場合:CommentToken、WhiteSpaceToken
文字列パターンがある場合:SymbolToken、WordToken、LiteralToken
public class CommentToken extends NonDocumentToken
{
    ・・・・
    
    //追加
    @Override
    public boolean match(EbnfCommentNode n)
    {
        TokenManager.getInstance().consumeToken();
        return true;
    }
}
public class LiteralToken extends NonDocumentToken
{
    ・・・・
    
    @Override
    public boolean match(EbnfLimitedLiteralNode n)
    {
        boolean retval = n.equals(m_str);
        if (retval)
        {
            TokenManager.getInstance().consumeToken();
        }
        else
        {
            //何もしない
        }
        
        return retval;
    }
}
XmlTokenSyntaxParserVisitorの検討と実装
■検討
基本以外で構文に出てくるトークンは、字句解析器の実装から
となるので、上記のノードを実装するXmlTokenSyntaxParserVisitorクラスを用意します。字句解析器の変更が必要なものはTokenManagerのnotifyメソッドで変更します。
■実装| ノード | : | トークン | 
| ―――――――――――――――――――――― | ||
| EbnfPIWordNode | : | PIWordToken | 
| EbnfPITargetNode | : | WordToken | 
| EbnfSystemLiteralNode | : | LiteralToken | 
| EbnfCharDataNode | : | CharDataToken | 
| EbnfCDataNode | : | CDataToken | 
| EbnfIgnoreNode | : | IgnoreWordToken | 
public abstract class XmlTokenSyntaxParserVisitor extends BaseTokenSyntaxParserVisitor
{
    public XmlTokenSyntaxParserVisitor()
    {
        super();
    }
    
    @Override
    public void visit(EbnfPIWordNode n)
    {
        m_tokenManager.notifyPIWordStart();
        Token token = m_tokenManager.nextToken();
        m_result = token.match(n);
        m_tokenManager.notifyPIWordEnd();
    }
    @Override
    public void visit(EbnfPITargetNode n)
    {
        Token token = m_tokenManager.nextToken();
        m_result = token.match(n);
    }
    @Override
    public void visit(EbnfSystemLiteralNode n)
    {
        Token token = m_tokenManager.nextToken();
        m_result = token.match(n);
    }
    @Override
    public void visit(EbnfCharDataNode n)
    {
        m_tokenManager.notifyCharDataStart();
        Token token = m_tokenManager.nextToken();
        m_result = token.match(n);
        m_tokenManager.notifyCharDataEnd();
    }
    @Override
    public void visit(EbnfCDataNode n)
    {
        m_tokenManager.notifyCDataStart();
        Token token = m_tokenManager.nextToken();
        m_result = token.match(n);
        m_tokenManager.notifyCDataEnd();
    }
    
    @Override
    public void visit(EbnfIgnoreNode n)
    {
        m_tokenManager.notifyIgnoreWordStart();
        Token token = m_tokenManager.nextToken();
        m_result = token.match(n);
        m_tokenManager.notifyIgnoreWordEnd();
    }
}
コメント
コメントを投稿する
SpecialPR