본문 바로가기
자바/자료구조

[자바][자료구조]재귀하향인터프리터

by 이얏호이야호 2020. 4. 3.

 

 

1.개요

제한된 프로그래밍 언어에 대한 간단한 인터프리터를 만들어 보기로 한다. 언어는 변수 선언, 반복문, 조건문, 함수 등 다양한 구성 요소를 갖지만 여기서는 전체적으로 인터프리터의 작동 원리를 이해하는데 초점을 맞추므로 간단한 배정문에 국한해서 인터프리터를 만들어 본다.

2.동작

public double parseStatement()

Statement는 오른쪽 Expression을 파싱한 결과를 왼쪽 식별자에게 배정하고 그 결과를 반환합니다. 배정은 TreeMapput 메소드 사용하여 심볼 테이블에 저장합니다. 만약 ‘;’로 끝나지 않는다면 오류메시지를 출력합니다.

public double parseExpression()

더하기‘+’와 빼기‘-’의 역할을 배정합니다.

public double parseTerm()

곱하기‘*’와 나누기‘/’의 역할을 배정합니다.

public double parseFactor()

FactorIdentifier, Number, 왼쪽 괄호 다음에 Expreesion이 오고 다음에 오른쪽 괄호가 오는 경우, 또는 마이너스 Factor4가지 경우를 파싱하여 그 결과를 반환합니다. 만약 없는 Variable이 들어온다면 오류메시지를 출력합니다.

 

 

 

3.코드

import jdk.nashorn.internal.runtime.regexp.joni.Syntax;

 

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.StreamTokenizer;

import java.util.Map;

import java.util.TreeMap;

 

public class TestInterpreter {

public static void main(String[] args) throws IOException {

StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));

Interpreter itp = new Interpreter(in);

double result;

while (true) {

in.nextToken();

if (in.ttype == '#')

break;

in.pushBack();

try {

result = itp.parseStatement();

System.out.println("=> " + result);

} catch (SyntaxError e) {

System.out.println("\n" + e.getMessage());

System.exit(1);

}

}

itp.printSymbolTable();

}

}

 

class Interpreter {

private Map<String, Double> st;

private StreamTokenizer in;

 

public Interpreter(StreamTokenizer in) throws IOException {

this.in = in;

st = new TreeMap<String, Double>();

in.ordinaryChar('/');

in.ordinaryChar('-');

}

 

public void printSymbolTable() {

for (Map.Entry<String, Double> entry : st.entrySet()) {

System.out.println(entry.getKey() + " = " + entry.getValue());

}

}

public double parseStatement() throws IOException, SyntaxError {

String Variable = "";

double result = 0;

while (true){

in.nextToken();

switch (in.ttype){

case '=':

result = parseExpression();

in.nextToken();

if(in.ttype != ';') throw new SyntaxError("wrong statement end symbol!");

st.put(Variable, result);

return result;

default:

Variable += in.sval;

}

}

}

public double parseExpression() throws IOException, SyntaxError {

double result = parseTerm();

while (true) {

in.nextToken();

switch (in.ttype) {

case '+':

result += parseTerm();

break;

case '-':

result -= parseTerm();

break;

default:

in.pushBack();

return result;

}

}

}

public double parseTerm() throws IOException, SyntaxError {

double result = parseFactor();

while (true){

in.nextToken();

switch (in.ttype){

case '*':

result *= parseFactor();

break;

case '/':

result /= parseFactor();

break;

default:

in.pushBack();

return result;

}

}

}

public double parseFactor() throws IOException, SyntaxError {

double result ;

while (true){

in.nextToken();

switch (in.ttype){

case '(':

result = parseExpression();

in.nextToken();

if(in.ttype != ')') throw new SyntaxError();

return result;

case '-':

result = parseFactor()*(-1);

return result;

default:

if(in.sval == null) return in.nval;

else if(st.get(in.sval) != null) return st.get(in.sval);

else{

throw new SyntaxError("Unkown variable!");

}

}

}

}

}

 

class SyntaxError extends Exception {

public SyntaxError() {

super("Error in Statement");

}

 

public SyntaxError(String msg) {

super(msg);

}

}

 

 

 

 

 

 

 

4.결과

 

 

 

 

 

댓글