This commit is contained in:
neoe 2019-06-25 13:23:24 +08:00
parent a8e6139ded
commit d4160a843c
6 changed files with 1 additions and 603 deletions

BIN
dist/luaformatter.jar vendored

Binary file not shown.

View File

@ -1,6 +1,6 @@
{ /* neoebuild script */
prjs:[
[luaformatter, "." , { main: "neoe.tools.LuaFormatter" }]
[luaformatter, "." , { main: "neoe.formatter.lua.LuaFormatter" }]
]
}

View File

@ -1,382 +0,0 @@
package neoe.tools;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import neoe.util.FileIterator;
import neoe.util.FileUtil;
public class LuaFormatter {
private static boolean TESTING_LEVEL = false;
private static boolean DEBUG = false;
public static void main(String[] args) throws Exception {
if (args.length == 0) {
usage();
} else {
new LuaFormatter().run(args);
}
}
private static void usage() {
System.out.println(
"luaformatter: args:\n -o -- overwrite source\n -e<ENCODING> -- use ENCODING\n -d -- debug\n input-files\n");
}
List<String> fs = new ArrayList<>();
private String encoding = "utf8";
private boolean overwritesource = false;
public void run(String[] args) throws Exception {
for (String s : args) {
if (s.startsWith("-")) {
doOpt(s);
} else {
addFile(s);
}
}
if (fs.isEmpty()) {
System.out.println("no input files");
} else {
for (String fn : fs) {
formatFile(fn);
}
}
}
private void addFile(String fn) {
File f = new File(fn);
if (f.isDirectory()) {
for (File f1 : new FileIterator(fn)) {
String name = f1.getName();
if (name.endsWith(".lua") && !name.endsWith(".fmt.lua") && !name.endsWith(".fmt-err.lua")) {
fs.add(f1.getAbsolutePath());
}
}
} else if (f.isFile()) {
fs.add(fn);
}
}
private void doOpt(String s) {
if (s.startsWith("-e")) {
encoding = s.substring(2);
} else if (s.startsWith("-o")) {
overwritesource = true;
} else if (s.startsWith("-d")) {
DEBUG = true;
TESTING_LEVEL = true;
overwritesource = false;
}
}
private Writer debug;
public void formatFile(String fn) {
try {
Env env = new Env();
if (DEBUG)
debug = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("debug.log"), "utf8"));
if (DEBUG)
debug.write("read " + fn + "\n");
String txt = FileUtil.readString(new FileInputStream(fn), encoding);
try {
String res = format(txt, env);
if (env.indent != 0) {
env.indent = 0;
throw new RuntimeException("indent not correct:" + fn);
}
File f2 = new File(fn + (overwritesource ? "" : ".fmt.lua"));
FileUtil.save(res.getBytes(encoding), f2.getAbsolutePath());
System.out.println("wrote to " + f2.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
File f2 = new File(fn + ".fmt-err.lua");
FileUtil.save(sb.toString().getBytes(encoding), f2.getAbsolutePath());
System.out.println("wrote to " + f2.getAbsolutePath());
}
if (DEBUG)
debug.close();
} catch (Exception e) {
e.printStackTrace();
System.err.printf("when formatting [%s]\n", fn);
}
}
StringBuilder sb;
LuaTokens tokens;
public String format(String txt, Env env) throws Exception {
sb = new StringBuilder();
tokens = new LuaTokens(txt);
loop(LuaTokenType.SPACE, null, null, env);
return sb.toString();
}
private void loop(LuaTokenType preType, String until, LuaTokenType operator, Env env) throws Exception {
env.lastType = preType;
addSpaceOnNeed(env);
while (true) {
Object[] tt = tokens.next();
if (tt == null)
break;
LuaTokenType type = (LuaTokenType) tt[0];
String token = (String) tt[1];
if (token == null)
break;
if (DEBUG) {
debug.write(String.format("t:%s,v:%s\n", type, token));
debug.flush();
}
addToken(type, token, env);
if (LuaTokenType.OPERATOR.equals(operator) && token.indexOf(until) >= 0) {
break;
}
if (until != null && token.equals(until)) {
break;
}
}
}
static class Env {
LuaTokenType lastType = LuaTokenType.SPACE;
int indent;
int changedLine;
String lastToken;
boolean forcedChangeLine;
Stack stack = new Stack();
}
private void addToken(LuaTokenType type, String token, Env env) throws Exception {
env.forcedChangeLine = false;
if (type.equals(LuaTokenType.COMMENT)) {
pre(env);
if (isMultiLineToken(token)) {
sb.append(token);
} else {
sb.append(normalComment(token.trim()));
}
} else if (type.equals(LuaTokenType.SPACE)) {
// sb.append("<sp cl=" + env.changedLine + ">");
int cnt = printSpaceLines(env, token);
if (cnt <= 0) {
addSpaceOnNeed(env);
} else {
env.changedLine = cnt;
}
// sb.append("</sp>");
} else if (type.equals(LuaTokenType.IDENTIFIER)) {
if ("end".equals(token)) {
String key = decIndent(env);
changeLineOnNeed(env);
printToken(env, token);
changeLineOnNeed(env);
if ("function".equals(key)) {
sb.append("\n");
env.changedLine++;
}
} else if ("else".equals(token)) {
String key = decIndent(env);
changeLineOnNeed(env);
printToken(env, token);
incIndent(env, key);
changeLineOnNeed(env);
} else if ("elseif".equals(token)) {
changeLineOnNeed(env);
String key = decIndent(env);
printToken(env, token);
} else if ("until".equals(token)) {
decIndent(env);
printToken(env, token);
} else if ("do".equals(token)) {
printToken(env, token);
incIndent(env, token);
changeLineOnNeed(env);
} else if ("local".equals(token)) {
changeLineOnNeed(env);
printToken(env, token);
} else if ("if".equals(token)) {
changeLineOnNeed(env);
printToken(env, token);
} else if ("then".equals(token)) {
printToken(env, token);
forceChangeLine(env);
incIndent(env, token);
} else if ("function".equals(token)) {
printToken(env, token);
env.changedLine = 0;
loop(type, ")", LuaTokenType.OPERATOR, env);
forceChangeLine(env);
incIndent(env, token);
} else if ("while".equals(token)) {
changeLineOnNeed(env);
printToken(env, token);
} else if ("for".equals(token)) {
changeLineOnNeed(env);
printToken(env, token);
} else if ("print".equals(token)) {
changeLineOnNeed(env);
printToken(env, token);
} else if ("repeat".equals(token)) {
changeLineOnNeed(env);
printToken(env, token);
forceChangeLine(env);
incIndent(env, token);
loop(type, "until", null, env);
} else {
printToken(env, token);
}
} else if (type.equals(LuaTokenType.OPERATOR)) {
if (token.equals(".")) {
sb.append(token);
} else if ("}])".indexOf(token) >= 0) {
decIndent(env);
printToken(env, token);
} else if ("{[(".indexOf(token) >= 0) {
printToken(env, token);
incIndent(env, token);
} else {
printToken(env, token);
}
} else {
printToken(env, token);
}
env.lastType = type;
env.lastToken = token;
}
private void printToken(Env env, String token) {
pre(env);
sb.append(token);
}
private int printSpaceLines(Env env, String token) {
int cnt = 0;
for (char c : token.toCharArray()) {
if (c == '\n') {
if (cnt >= env.changedLine) {
newline();
}
cnt++;
}
}
return cnt;
}
/** print indent if in newline or add a space */
private void pre(Env env) {
// sb.append("[cl=" + env.changedLine + "]");
if (env.changedLine > 0) {
printIndent(env);
env.changedLine = 0;
} else {
addSpaceOnNeed(env);
}
}
private String normalComment(String s) {
if (s.startsWith("--") && s.length() > 2 && s.charAt(2) != ' ' && s.charAt(2) != '-') {
s = "-- " + s.substring(2);
}
return s;
}
private boolean isMultiLineToken(String token) {
return token.startsWith("--[") && token.endsWith("]");// && token.contains("\n");
}
private void printIndent(Env env) {
if (TESTING_LEVEL)
sb.append("[" + env.indent + "]");
for (int i = 0; i < env.indent; i++) {
sb.append("\t");
}
}
private void incIndent(Env env, String key) {
// sb.append("[i++]");
env.indent++;
env.stack.push(key);
}
private void changeLineOnNeed(Env env) {
if (env.changedLine <= 0) {
newline();
env.forcedChangeLine = true;
env.changedLine = 1;
}
}
private void newline() {
int p = sb.length();
while (true) {
if (p <= 0)
break;
char c = sb.charAt(p - 1);
if (c == ' ' || c == '\t') {
p--;
sb.setLength(p);
} else
break;
}
sb.append("\n");
}
private void forceChangeLine(Env env) {
newline();
env.forcedChangeLine = true;
env.changedLine = 1;
}
private String decIndent(Env env) {
env.indent--;
// if (stack.isEmpty()) return "";
return (String) env.stack.pop();
}
private void addSpaceOnNeed(Env env) {
if (!env.lastType.equals(LuaTokenType.SPACE) && !".".equals(env.lastToken) && env.changedLine <= 0) {
sb.append(" ");
env.lastType = LuaTokenType.SPACE;
env.changedLine = 0;
}
}
}
/*-
* stat ::= while exp do block end
stat ::= repeat block until exp
stat ::= if exp then block {elseif exp then block} [else block] end
stat ::= for Name = exp , exp [, exp] do block end
stat ::= for namelist in explist do block end
function f () body end
*
*/

View File

@ -1,5 +0,0 @@
package neoe.tools;
public enum LuaTokenType {
COMMENT, SPACE, IDENTIFIER, STRING, OPERATOR,
}

View File

@ -1,178 +0,0 @@
package neoe.tools;
import java.util.Arrays;
import java.util.List;
public class LuaTokens {
private String txt;
private int p;
private LuaTokenType type;
public LuaTokens(String txt) {
this.txt = txt;
this.p = 0;
}
StringBuilder sb = new StringBuilder();
public Object[] next() {
if (p >= txt.length())
return null;
sb.setLength(0);
char c = txt.charAt(p);
if (isSpace(c)) {
type = LuaTokenType.SPACE;
sb.append(c);
p++;
char c2;
while (p < txt.length()) {
if (isSpace(c2 = txt.charAt(p))) {
sb.append(c2);
p++;
} else {
break;
}
}
return submit(type, sb.toString());
} else if (isIdentifier(c) || (/* negtive number */c == '-' && Character.isDigit(peek(1)))) {
type = LuaTokenType.IDENTIFIER;
sb.append(c);
p++;
char c2;
while (p < txt.length()) {
if (isIdentifier(c2 = txt.charAt(p))) {
sb.append(c2);
p++;
} else {
break;
}
}
return submit(type, sb.toString());
} else if (c == '-' && peek(1) == '-') {
type = LuaTokenType.COMMENT;
sb.append("--");
p += 2;
int level = peekLongBrackets();
if (level < 0) {
readUntil("\n");
if (p < txt.length()) {
sb.setLength(sb.length() - 1);
p--;
}
} else {
readUntilLongBrackets(level);
}
return submit(type, sb.toString());
} else if (c == '\'' || c == '"') {
type = LuaTokenType.STRING;
sb.append(c);
p++;
while (true) {
if (p >= txt.length())
break;
char c2 = txt.charAt(p++);
sb.append(c2);
if (c2 == c) {
break;
} else if (c2 == '\\') {
sb.append(txt.charAt(p++));
}
}
// readUntil("" + (char) c);
return submit(type, sb.toString());
} else {
int level = peekLongBrackets();
if (level < 0) {
type = LuaTokenType.OPERATOR;
sb.append(c);
p++;
while (true) {
String t = sb.toString() + (char) peek(0);
if (longOperaters.contains(t)) {
sb.append(txt.charAt(p++));
} else {
break;
}
}
return submit(type, sb.toString());
} else {
type = LuaTokenType.STRING;
readUntilLongBrackets(level);
return submit(type, sb.toString());
}
}
}
final static List<String> longOperaters = Arrays.asList(new String[] { "<=", ">=", "==", "~=", "//", ">>", "<<" });
// private boolean isOp1(char c) {
// return "[]{}()".indexOf(c) >= 0;
// }
private Object[] submit(LuaTokenType type, String s) {
return new Object[] { type, s };
}
// private boolean isOperator(char c) {
// return !isIdentifier(c) && !isSpace(c) && c != '"' && c != '\'' && !isOp1(c);
// }
private void readUntilLongBrackets(int level) {
// sb.append("<LV:" + level + ">");
StringBuilder sb = new StringBuilder("]");
for (int i = 0; i < level; i++) {
sb.append('=');
}
sb.append(']');
readUntil(sb.toString());
}
private int peekLongBrackets() {
if (peek(0) == '[') {
int lv = 0;
while (peek(lv + 1) == '=') {
lv++;
}
if (peek(1 + lv) == '[') {
return lv;
}
}
return -1;
}
private void readUntil(String s) {
int p1 = txt.indexOf(s, p);
if (p1 < 0) {
sb.append(txt.substring(p));
p = txt.length();
} else {
sb.append(txt.substring(p, p1 + s.length()));
p = p1 + s.length();
}
}
private char peek(int i) {
if (p + i >= txt.length())
return 0;
return txt.charAt(p + i);
}
private boolean isIdentifier(char c) {
return Character.isDigit(c) || Character.isLetter(c) || c == '_';
}
private boolean isSpace(char c) {
return Character.isWhitespace(c);
}
}

View File

@ -28,43 +28,6 @@ public class FileIterator implements Iterable<File> {
this.sortByName = sortByName;
}
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
Iterable<File> it = new FileIterator("C:/xxx");
int total = 0;
int dircnt = 0;
int[] linecnt = new int[2];
Map<String, Integer> cnt = new HashMap<String, Integer>();
for (File f : it) {
if (f.isDirectory()) {
dircnt++;
continue;
}
total++;
String fn = f.getName();
int p1 = fn.indexOf(".");
if (p1 > 0) {
String ext = fn.substring(p1);
Integer i = cnt.get(ext);
if (i == null) {
cnt.put(ext, 1);
} else {
cnt.put(ext, i + 1);
}
if (ext.equalsIgnoreCase(".xxx")) {
getLineCnt(f, linecnt);
}
}
System.out.println(f.getAbsolutePath());
}
System.out.println(cnt);
System.out.println(linecnt[0] + "," + linecnt[1] + "," + (linecnt[1] * 100 / linecnt[0]) + "%");
}
private static int getLineCnt(File f, int[] linecnt) throws Exception {
int cnt = 0;