Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * En rekursiv medåknings-parser för aritmetiska uttryck
- */
- public class Parser {
- private Lexer lexer;
- private int currentLine;
- private int lastInsLine;
- public Parser(Lexer lexer) {
- this.lexer = lexer;
- currentLine = 1;
- lastInsLine = 1;
- }
- public ParseTree parse() throws SyntaxError {
- // Startsymbol är start
- ParseTree result = start();
- // Borde inte finnas något kvar av indata när vi parsat ett uttryck
- if (lexer.nextToken().getType() != TokenType.EOF) {
- throw new SyntaxError(currentLine);
- }
- return result;
- }
- private ParseTree start() throws SyntaxError {
- maybespace();
- ParseTree result = null;
- if (isInstruction(lexer.peekToken().getType())) {
- lastInsLine = currentLine;
- result = instructionlist();
- }
- return result;
- }
- private void maybespace() throws SyntaxError {
- TokenType peek = lexer.peekToken().getType();
- while (peek == TokenType.WHITESPACE || peek == TokenType.NL || peek == TokenType.COMMENT) {
- if (peek == TokenType.NL)
- currentLine++;
- lexer.nextToken();
- peek = lexer.peekToken().getType();
- }
- }
- private void space() throws SyntaxError {
- TokenType peek = lexer.peekToken().getType();
- if (peek == TokenType.WHITESPACE || peek == TokenType.NL || peek == TokenType.COMMENT) {
- if(peek == TokenType.NL)
- currentLine++;
- lexer.nextToken();
- maybespace();
- }
- else
- throw new SyntaxError(lastInsLine);
- }
- private ParseTree instruction() throws SyntaxError {
- Token t = lexer.nextToken();
- TokenType nextToken;
- ParseTree result = null;
- switch (t.getType()) {
- case MOVE:
- lastInsLine = currentLine;
- space();
- nextToken = lexer.peekToken().getType();
- if (nextToken != TokenType.NUM) {
- if (isCode(nextToken))
- lastInsLine = currentLine;
- throw new SyntaxError(lastInsLine);
- }
- lastInsLine = currentLine;
- Integer steps = (Integer) lexer.nextToken().getData();
- Integer forwOrBack = (Integer) t.getData();
- result = new Move(steps*forwOrBack);
- maybespace();
- nextToken = lexer.nextToken().getType();
- if (nextToken != TokenType.DOT) {
- if (isCode(nextToken))
- lastInsLine = currentLine;
- throw new SyntaxError(lastInsLine);
- }
- lastInsLine = currentLine;
- break;
- case TURN:
- lastInsLine = currentLine;
- space();
- nextToken = lexer.peekToken().getType();
- if (nextToken != TokenType.NUM) {
- if (isCode(nextToken))
- lastInsLine = currentLine;
- throw new SyntaxError(lastInsLine);
- }
- lastInsLine = currentLine;
- Integer degrees = (Integer) lexer.nextToken().getData();
- Integer leftOrRight = (Integer) t.getData();
- result = new Turn(degrees*leftOrRight);
- maybespace();
- nextToken = lexer.nextToken().getType();
- if (nextToken != TokenType.DOT) {
- if (isCode(nextToken))
- lastInsLine = currentLine;
- throw new SyntaxError(lastInsLine);
- }
- lastInsLine = currentLine;
- break;
- case PEN:
- lastInsLine = currentLine;
- int upOrDown = (Integer) t.getData();
- result = new Pen(upOrDown);
- maybespace();
- nextToken = lexer.nextToken().getType();
- if (nextToken != TokenType.DOT) {
- if (isCode(nextToken))
- lastInsLine = currentLine;
- throw new SyntaxError(lastInsLine);
- }
- lastInsLine = currentLine;
- break;
- case COLOR:
- lastInsLine = currentLine;
- space();
- nextToken = lexer.peekToken().getType();
- if (nextToken != TokenType.HEX) {
- if (isCode(nextToken))
- lastInsLine = currentLine;
- throw new SyntaxError(lastInsLine);
- }
- lastInsLine = currentLine;
- String hex = (String) lexer.nextToken().getData();
- result = new Color(hex);
- maybespace();
- nextToken = lexer.nextToken().getType();
- if (nextToken != TokenType.DOT) {
- if (isCode(nextToken))
- lastInsLine = currentLine;
- throw new SyntaxError(lastInsLine);
- }
- lastInsLine = currentLine;
- break;
- case REP:
- lastInsLine = currentLine;
- space();
- nextToken = lexer.peekToken().getType();
- if (nextToken != TokenType.NUM) {
- if (isCode(nextToken))
- lastInsLine = currentLine;
- throw new SyntaxError(lastInsLine);
- }
- lastInsLine = currentLine;
- Integer repeat = (Integer) lexer.nextToken().getData();
- space();
- nextToken = lexer.peekToken().getType();
- if (nextToken != TokenType.QUOTATION) {
- if (isInstruction(nextToken)) {
- lastInsLine = currentLine;
- result = new Rep(repeat, instruction());
- }
- else
- throw new SyntaxError(lastInsLine);
- }
- else if (nextToken == TokenType.QUOTATION) {
- lastInsLine = currentLine;
- lexer.nextToken();
- maybespace();
- result = instruction();
- maybespace();
- if (isInstruction(lexer.peekToken().getType())) {
- lastInsLine = currentLine;
- result = new Branch(result, instructionlist());
- }
- result = new Rep(repeat, result);
- maybespace();
- if (lexer.nextToken().getType() != TokenType.QUOTATION)
- throw new SyntaxError(lastInsLine);
- lastInsLine = currentLine;
- }
- break;
- default:
- throw new SyntaxError(lastInsLine);
- }
- return result;
- }
- private ParseTree instructionlist() throws SyntaxError {
- ParseTree result = null;
- TokenType peek = lexer.peekToken().getType();
- if (isInstruction(peek)) {
- result = instruction();
- maybespace();
- TokenType next = lexer.peekToken().getType();
- if (isInstruction(next)){
- lastInsLine = currentLine;
- result = new Branch(result, instructionlist());
- }
- }
- return result;
- }
- private boolean isInstruction(TokenType t) {
- if (t == TokenType.MOVE || t == TokenType.TURN || t == TokenType.PEN
- || t == TokenType.COLOR || t == TokenType.REP)
- return true;
- return false;
- }
- private boolean isCode(TokenType t) {
- if(isInstruction(t) || t == TokenType.NUM || t == TokenType.HEX || t == TokenType.QUOTATION || t == TokenType.DOT)
- return true;
- return false;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement