📜  门| GATE-CS-2007 |问题5(1)

📅  最后修改于: 2023-12-03 14:58:28.053000             🧑  作者: Mango

GATE-CS-2007 Problem 5

This problem is about implementing a simple version of a compiler that translates a program in a programming language called "TINY" into an equivalent program in assembly language.

The TINY Programming Language

The TINY programming language has the following types of statements:

  1. Assignment statement: x := expr, where x is a variable and expr is an arithmetic or logical expression.

  2. Conditional statement: if cond then stmt1 else stmt2, where cond is a Boolean expression, stmt1 is a statement to execute if cond is true, and stmt2 is a statement to execute if cond is false.

  3. Loop statement: while cond do stmt, where cond is a Boolean expression and stmt is a statement to execute repeatedly as long as cond is true.

  4. Read statement: read x to read an integer value into variable x.

  5. Write statement: write expr to write the value of expr to the output.

The TINY Instruction Set

The TINY instruction set has the following instructions:

  1. ADD x,y: Add the contents of memory location x and memory location y and store the result in x.

  2. SUB x,y: Subtract the contents of memory location y from the contents of memory location x and store the result in x.

  3. MULT x,y: Multiply the contents of memory location x by the contents of memory location y and store the result in x.

  4. DIV x,y: Divide the contents of memory location x by the contents of memory location y and store the result in x.

  5. LOAD x: Load the contents of memory location x into the accumulator.

  6. STORE x: Store the contents of the accumulator into memory location x.

  7. READ x: Read an integer value from input and store it in memory location x.

  8. WRITE x: Write the contents of memory location x to the output.

  9. BRANCH x: Unconditional jump to the instruction at memory location x.

  10. BRANCHNEG x: Jump to the instruction at memory location x if the contents of the accumulator are negative.

  11. BRANCHZERO x: Jump to the instruction at memory location x if the contents of the accumulator are zero.

  12. HALT: Terminate the program.

Code Example

Here is an example program in the TINY programming language:

read x
read y
if x < y then
    write y
else
    write x

Here is the equivalent program in assembly language:

READ X
READ Y
SUB X,Y
BRANCHNEG ELSE
WRITE Y
BRANCH ENDIF
ELSE: WRITE X
ENDIF: HALT

To implement this conversion from TINY to assembly language, you could write a parser that translates each TINY statement into an equivalent sequence of assembly instructions. You could use a stack data structure to keep track of the state of the program, such as the nested structure of if-else blocks or while loops.

Code Implementation

Here is a Python implementation of a TINY to assembly language converter:

from typing import List, Tuple

def tiny_to_assembly(tiny_program: str) -> str:
    """Convert a TINY program to an equivalent program in assembly language."""
    assembly_program = ""
    tokens = tiny_program.split()
    i = 0
    while i < len(tokens):
        if tokens[i] == "read":
            assembly_program += f"READ {tokens[i+1]}\n"
            i += 2
        elif tokens[i] == "write":
            assembly_program += f"WRITE {tokens[i+1]}\n"
            i += 2
        elif tokens[i] == "if":
            cond_tokens = []
            j = i + 1
            while tokens[j] != "then":
                cond_tokens.append(tokens[j])
                j += 1
            then_tokens = []
            j += 1
            while tokens[j] != "else":
                then_tokens.append(tokens[j])
                j += 1
            else_tokens = []
            j += 1
            while tokens[j] != "endif":
                else_tokens.append(tokens[j])
                j += 1
            else_tokens.append("HALT")
            true_label = f"L{i}"
            false_label = f"L{j}"
            assembly_program += f"{compile_conditional(cond_tokens, true_label, false_label)}\n"
            assembly_program += f"{true_label}:\n"
            assembly_program += f"{compile_sequence(then_tokens)}\n"
            assembly_program += f"BRANCH {false_label}\n"
            assembly_program += f"{false_label}:\n"
            assembly_program += f"{compile_sequence(else_tokens)}\n"
            i = j + 1
        elif tokens[i] == "while":
            cond_tokens = []
            j = i + 1
            while tokens[j] != "do":
                cond_tokens.append(tokens[j])
                j += 1
            body_tokens = []
            j += 1
            while tokens[j] != "endwhile":
                body_tokens.append(tokens[j])
                j += 1
            body_tokens.append(f"BRANCH {i}")
            true_label = f"L{i}"
            false_label = f"L{j+1}"
            assembly_program += f"{true_label}:\n"
            assembly_program += f"{compile_conditional(cond_tokens, false_label, true_label)}\n"
            assembly_program += f"{false_label}:\n"
            assembly_program += f"{compile_sequence(body_tokens)}\n"
            i = j + 1
        else:  # assignment statement
            assembly_program += f"LOAD {tokens[i+2]}\n"
            if tokens[i+3] == "+":
                assembly_program += f"ADD {tokens[i+4]},{tokens[i+2]}\n"
            elif tokens[i+3] == "-":
                assembly_program += f"SUB {tokens[i+4]},{tokens[i+2]}\n"
            elif tokens[i+3] == "*":
                assembly_program += f"MULT {tokens[i+4]},{tokens[i+2]}\n"
            else:  # division
                assembly_program += f"DIV {tokens[i+4]},{tokens[i+2]}\n"
            assembly_program += f"STORE {tokens[i]}\n"
            i += 5  # skip over the whole assignment statement
    assembly_program += "HALT\n"
    return assembly_program

def compile_conditional(tokens: List[str], true_label: str, false_label: str) -> str:
    """Compile a conditional statement to assembly language."""
    op = tokens[1]
    if op == "<":
        return f"SUB {tokens[0]},{tokens[2]}\nBRANCHNEG {true_label}\nBRANCH {false_label}"
    elif op == ">":
        return f"SUB {tokens[2]},{tokens[0]}\nBRANCHNEG {true_label}\nBRANCH {false_label}"
    else:  # equality
        return f"SUB {tokens[0]},{tokens[2]}\nBRANCHZERO {true_label}\nBRANCH {false_label}"

def compile_sequence(tokens: List[str]) -> str:
    """Compile a sequence of statements to assembly language."""
    assembly = ""
    for i, token in enumerate(tokens):
        if token == ";":
            continue
        if token == "read" or token == "write":
            assembly += f"{tiny_to_assembly(f'{token} {tokens[i+1]}')}"
        elif token == "if":
            j = i + 1
            while tokens[j] != "endif":
                j += 1
            j += 1
            assembly += f"{tiny_to_assembly(' '.join(tokens[i:j]))}"
            i = j
        elif token == "while":
            j = i + 1
            while tokens[j] != "endwhile":
                j += 1
            j += 1
            assembly += f"{tiny_to_assembly(' '.join(tokens[i:j]))}"
            i = j
        else:  # assignment statement
            assembly += f"LOAD {tokens[i+2]}\n"
            if tokens[i+3] == "+":
                assembly += f"ADD {tokens[i+4]},{tokens[i+2]}\n"
            elif tokens[i+3] == "-":
                assembly += f"SUB {tokens[i+4]},{tokens[i+2]}\n"
            elif tokens[i+3] == "*":
                assembly += f"MULT {tokens[i+4]},{tokens[i+2]}\n"
            else:  # division
                assembly += f"DIV {tokens[i+4]},{tokens[i+2]}\n"
            assembly += f"STORE {tokens[i]}\n"
            i += 5  # skip over the whole assignment statement
    return assembly

This implementation uses recursion to handle nested if-else blocks and while loops. The compile_sequence function is used to compile a sequence of statements, and it calls the tiny_to_assembly function recursively as needed to handle all types of statements.

Conclusion

Implementing a compiler is a complex task that requires knowledge of programming language syntax and semantics, as well as skills in parsing and code generation. The TINY programming language and instruction set provide a simple yet powerful framework for demonstrating these concepts and for practicing programming skills.