Tokenizer类的框架

作用:用于代码编辑器中的括号匹配测试

package com.tokenizer.cc;

import java.io.IOException;
import java.io.PushbackReader;
import java.io.Reader;
/**
 * Tokenizer class.
 * @author SunnyBoy
 * @version Time:2017年8月3日 下午3:57:00
 */
public class Tokenizer {
    private PushbackReader in;// The input Stream
    private char ch;//Current character
    private int currentLine;//Current line
    private int errors;//Number of errors seen

    public static final int SLASH_SLAH = 0;
    public static final int SLASH_STAR = 1;

    public Tokenizer( Reader inStream) {
        errors = 0;
        ch = '\0';
        currentLine = 1;
        in = new PushbackReader(inStream);
    }

    public int getLineNumber() {
        return currentLine;
    }

    public int getErrorCount() {
        return errors;
    }
    /**
     * Get the next opening or closing symbol.
     * Return false if end of file.
     * Skip past comments and character and string constants
     */
    public char getNextOpenClose() {
        while(nextChar()) {
            if(ch == '/')
                processSlash();
            else if(ch == '\''||ch =='"')
                skipQuote(ch);
            else if(ch =='(' || ch == '[' || ch == '{' || ch ==')' || ch == ']' || ch == '}')
                return ch;
        }
        return '\0';
    }
    /**
     * @return next identifier.skipping comments
     * string constants.and character constants.
     * Place identifier in currentIdNode.word and return false
     * only if end of stream is reached.
     */
    public String getNextID() {
        while(nextChar()) {
            if(ch =='/')
                processSlash();
            else if(ch =='\\')
                nextChar();
            else if(ch =='\'' || ch =='"')
                skipQuote(ch);
            else if (!Character.isDigit(ch)&&isIdChar(ch))
                return getRemainingString();
        }
        return null;
    }
    /**
     * nextChar sets ch based on the next character in the input stream.
     * putBackChar puts thecharacter back onto the stream.
     * It should be used only once after a call to nextChar.
     * Both routines adjust currentLine if necessary.
     * @return
     */
    private boolean nextChar() {
        try {
            int readVal = in.read();
            if(readVal == -1)
                return false;
            ch = (char) readVal;
            if(ch == '\n')
                currentLine++;
            return true;
        }
        catch(IOException e) {
            return false;
        }
    }

    private void putBackChar() {
        if(ch == '\n')
            currentLine--;
        try {
            in.unread((int)ch);
        }catch(IOException e) {

        }
    }

    /**
     * Precondition: We are about to process a comment;
     *              have already seen comment-start token
     * Postcondition: Stream will be set immediately after 
     *              commment-ending token
     * @param start
     */
    private void skipComment(int start) {
        if(start == SLASH_SLAH) {
            while(nextChar()&&(ch!='\n'));
            return;
        }
        boolean state = false;

        while(nextChar()) {
            if(state&&ch=='/')
                return;
            state = (ch =='*');
        }
        errors++;
        System.out.println("Unterminated comment!");
    }
    /**
     * Precondition: We are about to process a quote;
     *                  have already seen beginning quote.
     * Postcondition: Stream will be set immediately after
     *                  matching quote
     * @param quoteType
     */
    private void skipQuote(char quoteType) {
        while(nextChar()) {
            if(ch == quoteType)
                return;
            if(ch == '\n') {
                errors++;
                System.out.println("Missing closed quote at line "+ currentLine);
                return;
            }
            else if(ch == '\\')
                nextChar();
        }
    }
    /**
     * After the opening slash is seen deal with next character.
     * If it is a comment starter. process it; otherwise putback
     * the next character if it is not a newline.
     */
    private void processSlash() {
        if (nextChar()) {
            if (ch == '*') {
                // Javadoc comment
                if (nextChar() && ch != '*')
                    putBackChar();
                skipComment(SLASH_STAR);

            } else if (ch == '/')
                skipComment(SLASH_SLAH);
            else if (ch == '\n')
                putBackChar();
        }
    }
    /**
     * Return true if ch can be part of a Java identifier
     * @param ch
     * @return
     */
    private static final boolean isIdChar(char ch) {
        return Character.isJavaIdentifierPart(ch);
    }
    /**
     * Return an identifier read from input stream
     * First character is already read into ch
     * @return
     */
    private String getRemainingString() {
        String result = ""+ch;
        for(;nextChar();result+=ch)
            if(!isIdChar(ch)) {
                putBackChar();
                break;
            }
        return result;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 训练自己的 tokenizer 通常需要以下几个步骤: 1. 准备数据: 选择一些文本数据作为训练数据, 并将其按照一定的方式拆分成若干个 token, 例如将句子按照空格拆分成单词. 2. 选择模型: 选择一种适合你的任务的模型, 例如基于字符的模型或基于单词的模型. 3. 训练模型: 使用你准备的数据来训练你选择的模型, 例如使用机器学习框架训练神经网络. 4. 评估模型: 使用一些测试数据来评估你训练出来的模型的效果, 并根据评估结果调整模型的超参数或模型结构. 5. 使用模型: 使用你训练好的模型来处理新的文本数据, 将其拆分成 token. ### 回答2: 要训练自己的tokenizer,首先需要明确目标语言和领域。以下是一些步骤和技巧: 1. 收集数据:根据目标语言和领域,收集大量的文本数据。这些数据可以来自书籍、新闻、网站、社交媒体等各种来源。 2. 数据清洗:对收集到的文本数据进行清洗,去除无用的标记、特殊字符和HTML标签等,确保数据干净且符合需要。 3. 分词:使用分词工具对文本进行分词,将文本拆分成单个的词语或标记。可以尝试不同的分词工具或算法,选择最适合的方法。 4. 标记化:根据需要,将分词后的词语或标记进行进一步标记,例如词性标注、命名实体识别等。 5. 构建词汇表:将所有的词语或标记收集起来,构建词汇表。可以根据词频或其他标准对词汇表进行筛选,选择合适的词语。 6. 训练tokenizer:使用选定的算法和参数,训练tokenizer模型。可以使用机器学习算法(如朴素贝叶斯、条件随机场等)或神经网络模型(如循环神经网络、Transformer等)进行训练。 7. 优化和调试:对训练得到的tokenizer进行优化和调试,调整参数、算法或模型结构,以获得更好的性能。 8. 评估和验证:使用一部分独立的数据对训练得到的tokenizer进行评估和验证,检查其分词效果和准确性。 9. 迭代改进:根据评估和验证的结果,不断迭代改进tokenizer,修正错误并优化性能。 10. 应用和部署:将训练得到的tokenizer应用到实际任务中,比如文本分、机器翻译、文本生成等。确保tokenizer在实际应用中的稳定性和可靠性。 通过上述步骤,可以训练自己的tokenizer,并根据实际需要进行定制化和改进,以提高文本处理的效果和准确性。 ### 回答3: 训练自己的tokenizer是一个复杂的任务,但可以通过以下步骤完成: 1. 收集训练数据:首先,您需要收集大量的文本数据作为训练材料。这些可以是各种型的文本,包括新闻文章、小说、科技论文等。确保覆盖各种语言和主题。 2. 清洗和预处理数据:在训练tokenizer之前,必须对数据进行清洗和预处理。这包括去除标点符号、数字、html标签等,并将文本转换为统一的小写形式。您可以使用Python中的各种文本处理库和正则表达式来执行这些任务。 3. 构建词汇表:接下来,构建一个词汇表,将文本数据中的所有单词都收集起来。可以使用Python中的Counter或者其他计数方法来统计单词的频率,并选择适当的阈值来筛选出需要包含在词汇表中的单词。确保词汇表足够大且具有多样性。 4. 训练tokenizer:使用收集到的文本数据和词汇表,利用机器学习或深度学习技术,训练一个tokenizer模型。常见的tokenizer模型包括基于规则的tokenizer、n-gram模型和基于深度学习的tokenizer模型,如BERT、GPT等。根据自己的需求和数据规模选择适合的模型。 5. 评估tokenizer性能:在训练完成后,使用一些测试数据来评估tokenizer的性能。您可以使用一些标准的性能指标,如准确率、召回率和F1分数等。通过评估结果,可以进一步优化tokenizer的效果。 6. 部署tokenizer:当tokenizer达到您的期望性能后,将其部署到实际应用中。您可以将tokenizer模型集成到自己的应用程序中,以便实时处理文本数据。 总而言之,训练自己的tokenizer是一个需要经验和技术的过程。其中关键的步骤包括数据收集、预处理、构建词汇表、训练模型和性能评估。经过反复优化和调整,您可以构建一个高性能的tokenizer来处理各种文本数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值