/* VerySimpleTemplatesのレクサー */ import java.io.*; /* トークン・データ */ class VSTToken { enum Kind {L_BRACE, R_BRACE, TEXT, EOF} final Kind kind; final String value; VSTToken(Kind kind, String value) { this.kind = kind; this.value = value; } } /* レクサー(字句解析系)*/ class VSTLexer { private PushbackReader input; public VSTLexer(Reader reader) { this.input = new PushbackReader(reader); } public VSTToken nextToken() throws IOException { int c = input.read(); switch (c) { case -1: return new VSTToken(VSTToken.Kind.EOF, ""); case '{': int c2 = input.read(); // 1文字先読み if (c2 == '{') { // エスケープされた左波括弧 return new VSTToken(VSTToken.Kind.TEXT, "{"); } if (c2 != -1) input.unread((char)c2); // 先読み分を戻す return new VSTToken(VSTToken.Kind.L_BRACE, ""); case '}': return new VSTToken(VSTToken.Kind.R_BRACE, ""); default: input.unread((char)c); return new VSTToken(VSTToken.Kind.TEXT, readText()); } } // EOF、または'{'か'}'が出現するまでテキストを読む private String readText() throws IOException { StringBuilder sb = new StringBuilder(); while (true) { int c = input.read(); if (c == -1 ) { break; } if (c == '{' || c == '}') { input.unread((char)c); break; } sb.append((char)c); } return sb.toString(); } /* テスト用のmain */ public static void main(String[] args) { Reader input = null; if (args.length == 0) { input = new InputStreamReader(System.in); } else { try { input = new FileReader(args[0]); } catch (Exception e) { System.err.println(e); System.exit(1); } } VSTLexer lexer = new VSTLexer(input); try { VSTToken tok; do { tok = lexer.nextToken(); if (tok.kind == VSTToken.Kind.TEXT) { System.out.println("'" + tok.value + "'"); } else { System.out.println(tok.value); } } while (tok.kind != VSTToken.Kind.EOF); } catch (Exception e) { System.err.println(e); System.exit(1); } System.exit(0); } }