KLo*_*ted 19 java analyzer lexical
我正在使用Lexical Analyzer程序,我正在使用Java.我一直在研究这个问题的答案,但直到现在我都找不到.这是我的问题:
输入:
System.out.println ("Hello World");
Run Code Online (Sandbox Code Playgroud)
期望的输出:
Lexeme----------------------Token
System [Key_Word]
. [Object_Accessor]
out [Key_Word]
. [Object_Accessor]
println [Key_Word]
( [left_Parenthesis]
"Hello World" [String_Literal]
) [right_Parenthesis]
; [statement_separator]
Run Code Online (Sandbox Code Playgroud)
我还是初学者,所以我希望你们能帮助我.谢谢.
mic*_*kig 46
您既不需要ANTLR也不需要Dragon书来手工编写简单的词法分析器.即使是用于更全面的语言(如Java)的词法分析器,手工编写也不是非常复杂.显然,如果您有工业任务,您可能需要考虑像ANTLR或某些词法变体这样的工业强度工具,但为了学习词汇分析的工作原理,手工编写可能会证明是一项有用的练习.我假设情况就是这样,因为你说你还是初学者.
这是一个简单的词法分析器,用Java编写,用于类似Scheme的语言的一个子集,我在看到这个问题之后写了这个.我认为代码相对容易理解,即使你之前从未见过lexer,只是因为将一串字符(在本例中为a String)分成一个标记流(在这种情况下为a List<Token>)并不那么难.如果您有疑问,我可以尝试更深入地解释.
import java.util.List;
import java.util.ArrayList;
/*
* Lexical analyzer for Scheme-like minilanguage:
* (define (foo x) (bar (baz x)))
*/
public class Lexer {
public static enum Type {
// This Scheme-like language has three token types:
// open parens, close parens, and an "atom" type
LPAREN, RPAREN, ATOM;
}
public static class Token {
public final Type t;
public final String c; // contents mainly for atom tokens
// could have column and line number fields too, for reporting errors later
public Token(Type t, String c) {
this.t = t;
this.c = c;
}
public String toString() {
if(t == Type.ATOM) {
return "ATOM<" + c + ">";
}
return t.toString();
}
}
/*
* Given a String, and an index, get the atom starting at that index
*/
public static String getAtom(String s, int i) {
int j = i;
for( ; j < s.length(); ) {
if(Character.isLetter(s.charAt(j))) {
j++;
} else {
return s.substring(i, j);
}
}
return s.substring(i, j);
}
public static List<Token> lex(String input) {
List<Token> result = new ArrayList<Token>();
for(int i = 0; i < input.length(); ) {
switch(input.charAt(i)) {
case '(':
result.add(new Token(Type.LPAREN, "("));
i++;
break;
case ')':
result.add(new Token(Type.RPAREN, ")"));
i++;
break;
default:
if(Character.isWhitespace(input.charAt(i))) {
i++;
} else {
String atom = getAtom(input, i);
i += atom.length();
result.add(new Token(Type.ATOM, atom));
}
break;
}
}
return result;
}
public static void main(String[] args) {
if(args.length < 1) {
System.out.println("Usage: java Lexer \"((some Scheme) (code to) lex)\".");
return;
}
List<Token> tokens = lex(args[0]);
for(Token t : tokens) {
System.out.println(t);
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用示例:
~/code/scratch $ java Lexer ""
~/code/scratch $ java Lexer "("
LPAREN
~/code/scratch $ java Lexer "()"
LPAREN
RPAREN
~/code/scratch $ java Lexer "(foo)"
LPAREN
ATOM<foo>
RPAREN
~/code/scratch $ java Lexer "(foo bar)"
LPAREN
ATOM<foo>
ATOM<bar>
RPAREN
~/code/scratch $ java Lexer "(foo (bar))"
LPAREN
ATOM<foo>
LPAREN
ATOM<bar>
RPAREN
RPAREN
Run Code Online (Sandbox Code Playgroud)
一旦你编写了这样的一个或两个简单词法分析器,你就会很好地理解这个问题是如何分解的.然后探索如何使用像lex这样的自动化工具会很有趣.基于正则表达式的匹配器背后的理论并不太难,但确实需要一段时间才能完全理解.我认为手工编写词法分析器可以激发这项研究,并帮助你更好地掌握这个问题,而不是深入研究将正则表达式转换为有限自动机(首先是NFA,然后是NFA到DFA)等理论的方法......涉及到该理论可以要立刻吸收很多东西,很容易被淹没.
就个人而言,虽然龙书很好而且非常彻底,但报道可能并不是最容易理解的,因为它的目的是完整,不一定是可访问的.在打开Dragon书之前,您可能想尝试一些其他编译器文本.这里有一些免费的书籍,有很好的介绍性报道,恕我直言:
http://www.ethoberon.ethz.ch/WirthPubl/CBEAll.pdf
http://www.diku.dk/~torbenm/Basics/
一些关于正则表达式实现的文章(自动词法分析通常使用正则表达式)
我希望有所帮助.祝好运.
| 归档时间: |
|
| 查看次数: |
48765 次 |
| 最近记录: |