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

第029回_条件付字句解析器5_EntityValue系Lexer他

»
今回は、EntityValueを解析する字句解析器を検討します。内容はAttValueとほとんど同じです。

字句解析器が必要な部分の洗い出し

第007回の内容から、
EntityValue ::= EntityValueDoubleQuoteStart | EntityValueQuoteStart
EntityValueDoubleQuoteStart ::= DoubleQuote EntityValueDoubleQuoteSection
EntityValueDoubleQuoteSection ::= (NORMAL_TOKEN_B1 | PEReference | Reference)* '"'
EntityValueQuoteStart ::= Quote EntityValueQuoteSection
EntityValueQuoteSection ::= (NORMAL_TOKEN_B2 | PEReference | Reference)* "'"
と構文を整理し、
No.条件トークン一覧
―――――――――――――――――――――――――――――――――――――
12EntityValueDoubleQuoteSectionを構文解析しているNORMAL_TOKEN_B1
SYMBOL ('%')
SYMBOL ('&'),
SYMBOL ('&#')
SYMBOL ('&#x')
13EntityValueQuoteSectionを構文解析している NORMAL_TOKEN_B2
SYMBOL ('%')
SYMBOL ('&'),
SYMBOL ('&#')
SYMBOL ('&#x')
を分類しましたので、EntityValueDoubleQuoteSectionLexer,EntityValueQuoteSectionLexerを実装します。
# DoubleQuoteLexerとQuoteLexerは
# AttValueと共通ですので今回の解説には含みません。

EntityValueDoubleQuoteSectionLexerの実装


public class EntityValueDoubleQuoteSectionLexer extends MapSwitchLexer
{
    private static final EntityValueDoubleQuoteSectionLexer
                m_instance = new EntityValueDoubleQuoteSectionLexer();
    
    private EntityValueDoubleQuoteSectionLexer()
    {
        super();
        
        //記号      処理
        //-----------------------------------------------------------------------------------------
        //'"'       初期化して、JustCreateSymbolTokenizerへ移動する
        //'%'       初期化して、JustCreateSymbolTokenizerへ移動する
        //'&'       初期化して、SymbolListTokenizer2へ移動する
        //その他    初期化して、NormalTokenB1Tokenizerへ移動する
        //EOF       EofTokenを作成する
        Init_MovePos oneCharSymbol
            = new Init_MovePos(new JustCreateSymbolTokenizer());
        Init_MovePos normalTokenB1Tokenizer
            = new Init_MovePos(new NormalTokenB1Tokenizer());
        ArrayList<String> list = new ArrayList<String>();
        // 先に#xを評価させないと#でOKになってしまうので注意
        list.add("#x");
        list.add("#");
        Init_MovePos  ampersandTokenizer
            = new Init_MovePos(new SymbolListTokenizer2(list));
        EofTokenizer eof         = new EofTokenizer();

        m_map.put('"'      , oneCharSymbol);
        m_map.put('%'      , oneCharSymbol);
        m_map.put('&'      , ampersandTokenizer);
        m_map.setOutOfRange(normalTokenB1Tokenizer);
        m_map.setEofFunctor(eof);
    }

    public static GeEntityValueDoubleQuoteSectionLexer getInstance()
    {
        return m_instance;
    }
}

NormalTokenB1Tokenizerの実装

実装はNormalTokenB1Tokenizerと後述するNormalTokenB2Tokenizerでほぼ同じなので、共通部分を抽象クラスNormalTokenBTokenizerとして用意します。

NormalTokenBTokenizer

public abstract class NormalTokenBTokenizer extends MapSwitchTokenizer
{
    private class NormalTokenMaker implements Functor
    {
        public NormalTokenMaker(){}
        
        @Override
        public Token tokenize(StringBuilder str, int pos)
        {
            return makeToken();
        }
    }

    public NormalTokenBTokenizer(char endChar)
    {
        super();
        
        //記号            処理
        //---------------------------------------------
        //endChar     今の文字を含めずに、NORMAL_TOKEN_Bを作成する
        //'&'         今の文字を含めずに、NORMAL_TOKEN_Bを作成する
        //'%'         今の文字を含めずに、NORMAL_TOKEN_Bを作成する
        //その他      今の文字を確定して、次へ
        //EOF         NORMAL_TOKEN_Bを作成する
        //
        NormalTokenMaker ntm = new NormalTokenMaker();
        Update_MovePos   rm  = new Update_MovePos();
        
        m_map.put(endChar , ntm);
        m_map.put('&'     , ntm);
        m_map.put('%'     , ntm);
        m_map.setOutOfRange(rm);
        m_map.setEofFunctor(ntm);
    }

    abstract Token makeToken();
}

NormalTokenB1Tokenizer

public class NormalTokenB1Tokenizer extends NormalTokenBTokenizer
{
    public NormalTokenB1Tokenizer()
    {
        super('\"');
    }

    protected Token makeToken()
    {
        return new NormalTokenB1Token();
    }
}

EntityValueQuoteSectionLexerの実装


public class EntityValueQuoteSectionLexer extends MapSwitchLexer
{
    private static final EntityValueQuoteSectionLexer
                m_instance = new EntityValueQuoteSectionLexer();

    private EntityValueQuoteSectionLexer()
    {
        super();
        
        //記号     処理
        //---------------------------------------------------
        //"'"      初期化して、JustCreateSymbolTokenizerへ移動する
        //'%'      初期化して、JustCreateSymbolTokenizerへ移動する
        //'&'      初期化して、SymbolListTokenizer2へ移動する
        //その他   初期化して、NormalTokenB2Tokenizerへ移動する
        //EOF       EofTokenを作成する
        Init_MovePos oneCharSymbol
            = new Init_MovePos(new JustCreateSymbolTokenizer());
        Init_MovePos normalTokenB2Tokenizer
            = new Init_MovePos(new NormalTokenB2Tokenizer());

        ArrayList<String> list = new ArrayList<String>();
        // 先に#xを評価させないと#でOKになってしまうので注意
        list.add("#x");
        list.add("#");
        Init_MovePos ampersandTokenizer
            = new Init_MovePos(new SymbolListTokenizer2(list));
        EofTokenizer eof         = new EofTokenizer();

        m_map.put('\''     , oneCharSymbol);
        m_map.put('%'      , oneCharSymbol);
        m_map.put('&'      , ampersandTokenizer);
        m_map.setOutOfRange(normalTokenB2Tokenizer);
        m_map.setEofFunctor(eof);
    }

    public static GeEntityValueQuoteSectionLexer getInstance()
    {
        return m_instance;
    }
}

NormalTokenB2Tokenizerの実装


public class NormalTokenB2Tokenizer extends NormalTokenBTokenizer
{
    public NormalTokenB2Tokenizer()
    {
        super('\'');
    }

    protected Token makeToken()
    {
        return new NormalTokenB2Token();
    }
}
Comment(0)

コメント

コメントを投稿する