ワイヤータッピングのデモ
檜山正幸
Fri Sep 29 2006
1. ワイヤータッピングのときに挿入するコンポネント
- TokenLogger : トークンの通過を記録する
- TokenChecker : トークンの値がnullでないかを検査
- TokenCaster : トークン通過を通知する
- TokenMonitor : TokenCasterからの通知を受けるインターフェース
- LoggingMonitor : トークンの通過を記録するモニター
/* TokenLogger.java */
package sample.misc;
import java.io.*;
import sample.*;
public class TokenLogger implements VSTLexerPI {
/* -- component ports */
// @Provide
public final VSTLexerPI lexerPro;
// @Require
public VSTLexerPI lexerReq;
// @Require(Occurence.OPTIONAL)
public void setOutput(Writer writer) {
output = new PrintWriter(writer);
}
// @Require(Occurence.OPTIONAL)
public void setOutput(OutputStream stream) {
setOutput(new OutputStreamWriter(stream));
}
/* -- end ports */
private PrintWriter output;
public TokenLogger() {
lexerPro = this;
setOutput(System.out);
}
public VSTToken nextToken() throws IOException {
VSTToken tok = lexerReq.nextToken();
if (tok.kind == VSTToken.Kind.TEXT) {
output.println("'" + tok.value + "'");
} else {
output.println(tok.value);
}
output.flush();
return tok;
}
}
/* TokenChecker.java */
package sample.misc;
import java.io.*;
import sample.*;
class NullValueViolation extends RuntimeException {
public NullValueViolation(String msg) {
super(msg);
}
}
public class TokenChecker implements VSTLexerPI {
/* -- component ports */
// @Provide
public final VSTLexerPI lexerPro;
// @Require
public VSTLexerPI lexerReq;
/* -- end ports */
public TokenChecker() {
lexerPro = this;
}
public VSTToken nextToken() throws IOException {
VSTToken tok = lexerReq.nextToken();
if (tok.value == null)
throw new NullValueViolation("value is null. kind=" + tok.kind);
return tok;
}
}
/* TokenCaster.java */
package sample.misc;
import java.util.*;
import java.io.*;
import sample.*;
import sample.misc.TokenMonitor;
public class TokenCaster implements VSTLexerPI {
// ※注意:シングルスレッドのみとして、排他制御はしない
/* -- component ports */
// @Provide
public final VSTLexerPI lexerPro;
// @Require
public VSTLexerPI lexerReq;
// @Require(Occurrence.ANY)
public void addMonitor(TokenMonitor mon) {
if (!monitorList.contains(mon)) monitorList.add(mon);
}
// @Require(Occurrence.ANY)
public void removeMonitor(TokenMonitor mon) {
monitorList.remove(mon);
}
/* -- end ports */
public TokenCaster() {
lexerPro = this;
}
public VSTToken nextToken() throws IOException {
VSTToken tok = lexerReq.nextToken();
sendTokenPassedEvent(tok);
return tok;
}
private List<TokenMonitor> monitorList = new ArrayList<TokenMonitor>();
public void sendTokenPassedEvent(VSTToken token) {
for (TokenMonitor mon : monitorList) {
mon.tokenPassed(token);
}
}
}
/* LoggingMonitor.java */
package sample.misc;
import java.io.*;
import sample.*;
import sample.misc.TokenMonitor;
public class LoggingMonitor implements TokenMonitor {
/* -- component ports */
// @Provide
public final TokenMonitor monitor;
// @Require(Occurrence.OPTIONAL)
public void setOutput(Writer writer) {
output = new PrintWriter(writer);
}
// @Require(Occurrence.OPTIONAL)
public void setOutput(OutputStream stream) {
setOutput(new OutputStreamWriter(stream));
}
/* -- end ports */
private PrintWriter output;
public LoggingMonitor() {
monitor = this;
setOutput(System.out);
}
public void tokenPassed(VSTToken tok) {
if (tok.kind == VSTToken.Kind.TEXT) {
output.println("'" + tok.value + "'");
} else {
output.println(tok.value);
}
output.flush();
}
}
/* TokenMonitor.java */
package sample.misc;
import sample.VSTToken;
public interface TokenMonitor {
public void tokenPassed(VSTToken token);
}
/* LoggingMonitor.java */
package sample.misc;
import java.io.*;
import sample.*;
import sample.misc.TokenMonitor;
public class LoggingMonitor implements TokenMonitor {
/* -- component ports */
// @Provide
public final TokenMonitor monitor;
// @Require(Occurrence.OPTIONAL)
public void setOutput(Writer writer) {
output = new PrintWriter(writer);
}
// @Require(Occurrence.OPTIONAL)
public void setOutput(OutputStream stream) {
setOutput(new OutputStreamWriter(stream));
}
/* -- end ports */
private PrintWriter output;
public LoggingMonitor() {
monitor = this;
setOutput(System.out);
}
public void tokenPassed(VSTToken tok) {
if (tok.kind == VSTToken.Kind.TEXT) {
output.println("'" + tok.value + "'");
} else {
output.println(tok.value);
}
output.flush();
}
}
2. ワイヤータッピングのデモ
- VSTDemo1 : 標準的な接続
- VSTDemo2 : TokenLoggerを挿入
- VSTDemo3 : TokenCheckerを挿入
- VSTDemo4 : TokenCheckerを挿入し、レクサーをNullLexerに
- VSTDemo5 : TokenCasterとLoggingMonitorでログ機能を実現
/* VSTDemo1.java */
package sample;
import java.io.*;
class VSTDemo1 {
public static void main(String[] args) {
// inputの準備
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);
}
}
// parserの準備
VSTParserPI parser;
// 生成
VSTLexerCmp lexerCmp = new VSTLexerCmp();
VSTParserCmp parserCmp = new VSTParserCmp();
// ワイヤリング
lexerCmp.setInput(input);
parserCmp.lexer = lexerCmp.lexer;
parser = parserCmp.parser;
// 実行
try {
parser.parse();
} catch (Exception e) {
System.err.println(e);
System.exit(1);
}
System.exit(0);
}
}
/* VSTDemo2.java */
package sample;
import java.io.*;
import sample.misc.TokenLogger;
class VSTDemo2 {
public static void main(String[] args) {
// inputの準備
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);
}
}
// parserの準備
VSTParserPI parser;
// outputの準備
Writer output = null;
try {
output = new FileWriter("tokens.log");
} catch (Exception e) {
System.err.println(e);
System.exit(1);
}
// 生成
VSTLexerCmp lexerCmp = new VSTLexerCmp();
VSTParserCmp parserCmp = new VSTParserCmp();
TokenLogger logger = new TokenLogger();
// ワイヤリング
lexerCmp.setInput(input);
logger.setOutput(output);
logger.lexerReq = lexerCmp.lexer;
parserCmp.lexer = logger.lexerPro;
parser = parserCmp.parser;
// 実行
try {
parser.parse();
} catch (Exception e) {
System.err.println(e);
System.exit(1);
}
System.exit(0);
}
}
/* VSTDemo3.java */
package sample;
import java.io.*;
import sample.misc.TokenChecker;
class VSTDemo3 {
public static void main(String[] args) {
// inputの準備
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);
}
}
// parserの準備
VSTParserPI parser;
// 生成
VSTLexerCmp lexerCmp = new VSTLexerCmp();
VSTParserCmp parserCmp = new VSTParserCmp();
TokenChecker checker = new TokenChecker();
// ワイヤリング
lexerCmp.setInput(input);
checker.lexerReq = lexerCmp.lexer;
parserCmp.lexer = checker.lexerPro;
parser = parserCmp.parser;
// 実行
try {
parser.parse();
} catch (Exception e) {
System.err.println(e);
System.exit(1);
}
System.exit(0);
}
}
/* VSTDemo4.java */
package sample;
import java.io.*;
import sample.misc.TokenChecker;
class NullLexer implements VSTLexerPI {
public VSTToken nextToken() throws IOException {
return new VSTToken(VSTToken.Kind.TEXT, null);
}
}
class VSTDemo4 {
public static void main(String[] args) {
// inputの準備
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);
}
}
// parserの準備
VSTParserPI parser;
// 生成
VSTParserCmp parserCmp = new VSTParserCmp();
TokenChecker checker = new TokenChecker();
// ワイヤリング
checker.lexerReq = new NullLexer();
parserCmp.lexer = checker.lexerPro;
parser = parserCmp.parser;
// 実行
try {
parser.parse();
} catch (Exception e) {
System.err.println(e);
System.exit(1);
}
System.exit(0);
}
}
/* VSTDemo5.java */
package sample;
import java.io.*;
import sample.misc.TokenCaster;
import sample.misc.LoggingMonitor;
class VSTDemo5 {
public static void main(String[] args) {
// inputの準備
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);
}
}
// parserの準備
VSTParserPI parser;
// outputの準備
Writer output = null;
try {
output = new FileWriter("tokens.log");
} catch (Exception e) {
System.err.println(e);
System.exit(1);
}
// 生成
VSTLexerCmp lexerCmp = new VSTLexerCmp();
VSTParserCmp parserCmp = new VSTParserCmp();
TokenCaster caster = new TokenCaster();
LoggingMonitor logMonitor = new LoggingMonitor();
// ワイヤリング
lexerCmp.setInput(input);
logMonitor.setOutput(output);
caster.lexerReq = lexerCmp.lexer;
caster.addMonitor(logMonitor.monitor);
parserCmp.lexer = caster.lexerPro;
parser = parserCmp.parser;
// 実行
try {
parser.parse();
} catch (Exception e) {
System.err.println(e);
System.exit(1);
}
System.exit(0);
}
}