首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Java中如何在标记化时处理运算符(StreamTokenizer)

在Java中如何在标记化时处理运算符(StreamTokenizer)
EN

Stack Overflow用户
提问于 2011-04-19 05:59:22
回答 5查看 3.1K关注 0票数 3

我正在用Java编写一个记号赋予器,它必须处理操作符,并且记号之间的空格字符不是必需的。

我需要将"<=“之类的东西识别为标记,同时还需要识别"<”和"=“。

现在我有:

代码语言:javascript
复制
if (token == '<')
        if (nextToken == '=')
            this.tokenList.add(27); // <=
        else
            // add 2 tokens separately

有没有办法让StreamTokenizer自己来做这件事?我已经通读了API,但我什么也没看到。

我可以指定可以算作一个的令牌组合吗?理想情况下,getNextToken会一次删除两个令牌。

谢谢!

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-04-19 07:29:48

StreamTokenizer为您提供的是基本词法分析器的功能。你必须使用这些来制作你的高端版本。

您必须非常明智地使用nextToken()pushBack()。例如,在下面的示例中,我负责处理<<<<=。如果您看到操作符<,则向前查看流中的线索,如果没有找到后面的<=,则将look ahead标记推回到流中。

>>示例代码

代码语言:javascript
复制
import java.io.IOException;
import java.io.StreamTokenizer;
import java.io.StringReader;

public class LexerTest 
{
    private StringReader r;

    public LexerTest(StringReader stringReader) {
        r = stringReader;
    }

    public static void main(String[] args) throws IOException 
    {
        String s = "test = test1 + (test2 * test3 * (test4 - 2);";
        new LexerTest(new StringReader(s)).printTokens();

        System.out.println("\n### Test 2 ###\n");
        s = "test = if(test1 < test2){ test3 = (test4 - 2);}";
        new LexerTest(new StringReader(s)).printTokens();

        System.out.println("\n### Test 3 ###\n");
        s = "test = if(test1 <= test2){ test3 = (test4 - 2);}";
        new LexerTest(new StringReader(s)).printTokens();

        System.out.println("\n### Test 4 ###\n");
        s = "test = if(test1 < test2){ test3 = (test4 << 2);}";
        new LexerTest(new StringReader(s)).printTokens();
    }

    private void printTokens() throws IOException 
    {
        StreamTokenizer st = new StreamTokenizer(r);
        st.eolIsSignificant(true);

        int token = st.nextToken();
        while (token != StreamTokenizer.TT_EOF) 
        {
            token = st.nextToken();
            switch (token) 
            {
            case StreamTokenizer.TT_NUMBER:
                double num = st.nval;
                System.out.println("Number found: " + num);
                break;
            case StreamTokenizer.TT_WORD:
                String word = st.sval;
                System.out.println("Word found: " + word);
                break;
            case '+':
                break;
            case '-':
                break;
            case '/':
                break;
            case '*':
                break;
            case '<':
            {
                int t = st.nextToken();
                switch(t)
                {
                case '=':
                    System.out.println("<=");
                    break;
                case '<':
                    System.out.println("<<");
                    break;
                    default:
                        st.pushBack();
                        System.out.println("<");
                        break;
                }
            }
            }
        }

    }
}

希望这能有所帮助。

票数 3
EN

Stack Overflow用户

发布于 2011-04-19 06:59:54

对于所提供的记号赋予器类,这不是一个典型的场景。更像是一个成熟的解析器必须处理的东西。即使您需要手动构建这样的记号生成器,您也会发现研究由解析器生成器(如javacc或antlr )生成的代码是很有教育意义的。专注于他们如何处理“前瞻”,这就是你在这里问的。

除非这是一个作业问题,不允许使用解析器生成器,否则使用解析器生成器会得到更好的结果。

票数 2
EN

Stack Overflow用户

发布于 2011-04-19 07:00:27

看起来StreamTokenizer有点太基础了。

我建议你在StreamTokenizer之上构建一个词法分析器。这个词法分析器所做的就是在通常意义上给你一个实际的令牌流。也就是说,<=将作为单个令牌给出,而不是两个单独的令牌。

更好的方法是,将StreamTokenizer绑定并编写一个只直接查看字符的lexer。StreamTokenizer所做的工作太少,对解析高级语法没有用处。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5709393

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档