第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