我是一名学生程序员,我正在尝试为我的计算机科学类(class)之一构建 HTML 代码的词法分析器,其中输出应该是 HTML 代码的各个标记和词位。但是当我编译并运行分析器时,输出似乎有问题。
给出以下 HTML 代码:
<table>
<tr><td>temp</td><td>temp2</td></tr>
</table>
输出应该是:
TOKEN LEXEME
------------------
TAGIDENT <table
GTHAN >
TAGIDENT <tr
GTHAN >
TAGIDENT <td
GTHAN >
IDENT temp
ENDTAGHEAD </
IDENT td
GTHAN >
TAGIDENT <td
GTHAN >
IDENT temp2
ENDTAGHEAD </
IDENT td
GTHAN >
ENDTAGHEAD </
IDENT tr
GTHAN >
目前,这是我的代码:
import java.io.*;
import java.util.*;
public class LexAnalyzer {
public static void main(String[] args) {
try {
String input = "" , s = "";
Token t;
BufferedReader in = new BufferedReader(new FileReader(new File("Sample.html")));
while((s = in.readLine()) != null) {
input += s;
}
System.out.println(input);
System.out.println("TOKEN LEXEME");
System.out.println("------------------");
ArrayList<Token> a = getToken(input);
for(int i = 0; i < a.size(); i++) {
System.out.println(a.get(i).getId() + " " + a.get(i).getLexeme());
}
}
catch(Exception e) {
e.printStackTrace();
}
}
public static ArrayList<Token> getToken(String input) {
String lexeme = ""; //lexeme = TOKEN = ie. TAGIDENT
Token t = null;
ArrayList<Token> a = new ArrayList<Token>();
for(int i = 0; i < input.length(); i++) {
if(input.charAt(i) == '<') {
lexeme += input.charAt(i);
i++;
//case 1: if followed by ! < = COMMENT
if(input.charAt(i) == '!') {
lexeme += input.charAt(i);
i++;
while(input.charAt(i) != '>') {
lexeme += input.charAt(i);
i++;
}
input = input.substring(lexeme.length(), input.length());
}
//case 2: if followed by letter < = TAGIDENT
else if(isALetter(input.charAt(i))) {
lexeme += input.charAt(i);
i++;
while(input.charAt(i) != '>' && input.charAt(i) != ' ') {
lexeme += input.charAt(i);
i++;
}
t = new Token("TAGIDENT", lexeme);
input = input.substring(lexeme.length(), input.length());
a.add(t);
}
//case 3: if followed by number or space < = LTHAN
else if((isANumber(input.charAt(i)))) {
lexeme += input.charAt(i);
i++;
while(input.charAt(i) != '<' || input.charAt(i) == ' ') {
lexeme += input.charAt(i);
i++;
}
t = new Token("LTHAN", lexeme);
input = input.substring(lexeme.length(), input.length());
a.add(t);
}
//case 4: if followed by / < = ENDTAGHEAD
else if(input.charAt(i) == '/') {
lexeme += input.charAt(i);
i++;
//case 5: after ENDTAGHEAD -> IDENT
if(isALetter(input.charAt(i))) {
lexeme += input.charAt(i);
i++;
while(input.charAt(i) != '>') {
lexeme += input.charAt(i);
i++;
}
t = new Token("IDENT", lexeme);
input = input.substring(lexeme.length(), input.length());
a.add(t);
}
t = new Token("ENDTAGHEAD", lexeme);
input = input.substring(lexeme.length(), input.length());
a.add(t);
}
}
else if(input.charAt(i) == '>') {
lexeme += input.charAt(i);
i++;
t = new Token("GTHAN", lexeme);
input = input.substring(lexeme.length(), input.length());
}
}
return a;
}
public static boolean isALetter(char inputChar) {
Boolean itIsALetter = false;
if("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM".indexOf(inputChar) != -1) {
itIsALetter = true;
}
return itIsALetter;
}
public static boolean isANumber(char inputChar) {
Boolean itIsANumber = false;
if("1234567890".indexOf(inputChar) != -1) {
itIsANumber = true;
}
return itIsANumber;
}
}
token 类别:
public class Token {
String id, lexeme;
public Token(String id, String lexeme) {
this.id = id;
this.lexeme = lexeme;
}
public String getId() {
return id;
}
public String getLexeme() {
return lexeme;
}
}
我的代码的输出:
TOKEN LEXEME
------------------
TAGIDENT <table
IDENT <table>></td
ENDTAGHEAD <table>></td
关于如何修复我的代码有什么建议吗?非常感谢!
最佳答案
每当您读取 token 时:
while(input.charAt(i) != '>' && input.charAt(i) != ' ') {
lexeme += input.charAt(i);
i++;
}
您应该在 while 循环之后再添加一行:
lexeme += input.charAt(i);
为了读取最后一个结束字符>
。一旦您修复了代码中的所有这些位置(或者更好的是,重构您的代码并将其提取到外部帮助器方法) - 您将获得完整的 token 。
关于java - 使用 Java 的 HTML 词法分析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21507331/