我正在尝试使用字符串标记符读取文件的内容并将所有标记存储在数组中,但我在主错误中不断出现异常。我需要建议如何做到这一点。下面是我正在使用的代码;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.StringTokenizer;
public class FileTokenizer
{
private static final String DEFAULT_DELIMITERS = "< , { } >";
private static final String DEFAULT_TEST_FILE = "trans1.txt";
public List<String> tokenize(Reader reader) throws IOException
{
List<String> tokens = new ArrayList<String>();
BufferedReader br = null;
try
{
int i = 0;
br = new BufferedReader(reader);
Scanner scanner = new Scanner(br);
while (scanner.hasNext())
{
StringTokenizer st = new StringTokenizer(scanner.next(), DEFAULT_DELIMITERS, true);
while (st.hasMoreElements())
{
String[] t = new String[200];
tokens.add(st.nextToken());
t[i] = st.nextToken();
System.out.println(t[i]);
i++;
}
}
}
finally
{
close(br);
}
return tokens;
}
public static void close(Reader r)
{
try
{
if (r != null)
{
r.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
try
{
String fileName = ((args.length > 0) ? args[0] : DEFAULT_TEST_FILE);
FileReader fileReader = new FileReader(new File(fileName));
FileTokenizer fileTokenizer = new FileTokenizer();
List<String> tokens = fileTokenizer.tokenize(fileReader);
//System.out.println(tokens);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
我的文件看起来像;
PDA = (
{ q1, q2, q3, q4},
{ 0, 1 },
{ 0, $ },
{ (q1, @, @) -> { (q2, $) }, (q2, 0, @) -> { (q2, 0) },
(q2, 1, 0) -> { (q3, @) }, (q3, 1, 0) -> { (q3, @) },
(q3, @, $) -> { (q4, @) } },
q1,
{ q1, q4}
)
答案 0 :(得分:1)
你将得到java.util.NoSuchElementException,因为你在循环中调用了两次st.nextToken() while(st.hasMoreElements())
修改harigm的示例,然后可以根据需要将t [i]添加到令牌中
String [] t = new String [200];
的System.out.println(T [1]);
tokens.add(T [1]);
答案 1 :(得分:1)
分隔符不应以空格分隔:
private static final String DEFAULT_DELIMITERS = "<,{}>";
另外,请记住以下内容(来自Javadoc):
StringTokenizer是一个遗留类,出于兼容性原因而保留,尽管在新代码中不鼓励使用它。建议任何寻求此功能的人都使用String的split方法或java.util.regex包。
String.split()是在JDK 1.4中引入的。
那说:
st.nextToken()
两次; t
没用。您每次在内循环中重新创建它并仅使用它的一个元素。您正在尝试构建的是一个词法分析器。也许你应该查阅一些关于这个主题的文档。
答案 2 :(得分:0)
HI,
我修改了你的代码,现在工作得非常好,请查看
package org.sample;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.StringTokenizer;
public class FileTokenizer
{
private static final String DEFAULT_DELIMITERS = "< , { } >";
// private static final String DEFAULT_TEST_FILE = "trans1.txt";
public List<String> tokenize(Reader reader) throws IOException
{
List<String> tokens = new ArrayList<String>();
BufferedReader br = null;
try
{
int i = 0;
br = new BufferedReader(reader);
Scanner scanner = new Scanner(br);
while (scanner.hasNext())
{
StringTokenizer st = new StringTokenizer(scanner.next(), DEFAULT_DELIMITERS, true);
while (st.hasMoreElements())
{
String[] t = new String[200];
// tokens.add(st.nextToken());
// t[i] = st.nextToken();
System.out.println(t[i]);
i++;
}
}
}
finally
{
close(br);
}
return tokens;
}
public static void close(Reader r)
{
try
{
if (r != null)
{
r.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
try
{
// String fileName = ((args.length > 0) ? args[0] : DEFAULT_TEST_FILE);
FileReader fileReader = new FileReader(new File("c:\\DevTest\\1.txt"));
FileTokenizer fileTokenizer = new FileTokenizer();
List<String> tokens = fileTokenizer.tokenize(fileReader);
//System.out.println(tokens);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
答案 3 :(得分:0)
查看输入文件,我应该指出它的分层和不规则结构使它更适合由实际的解析器解析。您可能必须学习如何使用解析器生成器并为其编写词法分析器和语法等,但最终您将得到更易于维护的代码。自己这样做是相当费力和容易出错的。
我建议ANTLR。它非常成熟,并且拥有足够广泛的用户群,我相信你可以轻松获得帮助。