Sie sind auf Seite 1von 6

COS30023 Semester 2, 2019 Dr.

Markus Lumpe

Swinburne University of Technology

Faculty of Science, Engineering and Technology

LABORATORY COVER SHEET

Subject Code: COS30023


Subject Title: Languages in Software Development
Title: Abstract Syntax – RPN – Stack Machine
Lecturer: Dr. Markus Lumpe

Figure 1: CDC 6400, the first PASCAL host computer at ETH Zürich.1

1
http://www.moorecad.com/standardpascal/cdc6400.html

1
COS30023 Semester 2, 2019 Dr. Markus Lumpe

Abstract Syntax – RPN – Stack Machine

Reverse Polish notation (RPN) is a mathematical notation in which expressions are expressed
in postfix notation, that is, every operator follows all of its operands. For example, using RPN
we write
34+
to denote the sum of 3 and 4.
Expressions in RPN are evaluated left-to-right. The infix expression 5 + ((1 + 2) * 4) – 3 yields
the following RPN expression
512+4*+3-
To obtain an RPN expression from a given infix expression, we perform three steps:
• add parentheses to all sub terms
• move operator within parenthesized sub term to left
• remove all parentheses for the expression.
For example:
5 + ((1 + 2) * 4) - 3
è (5 + ((1 + 2) * 4)) - 3
è ((5 + ((1 + 2) * 4)) - 3)
è ((5 ((1 2 +) 4 *) +) 3 -)
è 512+4*+3-
An implementation for RPN is a stack machine that uses a pushdown stack rather than
individual machine registers to evaluate sub-expressions in a program. In particular, a stack
machine is programmed with a reverse Polish notation instruction set (sometimes called P-
code in reference to Pascal’s RPN implementation). The semantics of an instruction is given
by its stack transitions. For example, the following describes a binary operation that removes
its operands from the top of the stack and pushes the result back onto the stack:
…, operand1, operand2 à …, result
A given operation may have additional side effects. Storing and loading data from memory or
sending data to the output is considered a side effect for the stack machine.
The purpose of this self-study project is to develop a front-end for a stack machine, set up
the abstract syntax for the reverse Polish notation instruction set, and define an unparse
facility (using Java’s toString() method) to test whether the front-end has successfully
processed its input.

2
COS30023 Semester 2, 2019 Dr. Markus Lumpe

RPN grammar:

Program ::= (PCodeInstruction)* <EOF>


PCodeInstruction ::= “print” <String>
| “add”
| “sub”
| “mul”
| “div”
| “dup”
| “load” PCodeArgument
| “store” <Variable>
PCodeArgument ::= <Variable>
| <Number>

Lexical formation:

• <Variable> is a non-empty sequence is letters, digits, and underscore starting with $.


• <Number> is a IEEE floating point literal defined in problem set 4.
• <String> is any sequence of characters enclosed in matching double quotes (ie., “ ”).
• White space characters (\n, \r, space, \t, and a single line comment) have to be skipped.

A valid PCode program, including intermittent outputs, for $x = 4 * 2 + 1 reads:


load 4
load 2
mul
dup
print "4 * 2 = "
load 1
add
dup
print "4 * 2 + 1 = "
store $x

3
COS30023 Semester 2, 2019 Dr. Markus Lumpe

PCodeParser skeleton:

options
{
STATIC = false;
OUTPUT_DIRECTORY = "parser";
}

PARSER_BEGIN(PCodeParser)

package parser;

import java.io.*;
import java.util.*;
import ast.*;

public class PCodeParser


{
public static void main( String[] args )
{
try
{
PCodeParser lParser = new PCodeParser( new FileInputStream( args[0] ) );

ArrayList< PCode > lInstructions = lParser.Program();

System.out.println( "PCode accepted:" );


for ( PCode pc : lInstructions )
{
System.out.println( pc );
}
}
catch (ParseException e)
{
System.out.println( "Syntax Error : \n"+ e.toString() );
}
catch( java.io.FileNotFoundException e )
{
System.err.println( e.toString() );
}
}
}

PARSER_END(PCodeParser)

4
COS30023 Semester 2, 2019 Dr. Markus Lumpe

Abstract syntax:

The abstract syntax for the PCode instructions has to be derived from:
• class Position:
package ast;

import parser.Token;

public abstract class Position


{
protected int fBeginLine;
protected int fBeginColumn;
protected int fEndLine;
protected int fEndColumn;

public Position( Token aStart, Token aEnd )


{
fBeginLine = aStart.beginLine;
fBeginColumn = aStart.beginColumn;
fEndLine = aEnd.endLine;
fEndColumn = aEnd.endColumn;
}

public Position( Token aToken )


{
this( aToken, aToken );
}

public Position( Token aToken, Position aEnd )


{
fBeginLine = aToken.beginLine;
fBeginColumn = aToken.beginColumn;
fEndLine = aEnd.fEndLine;
fEndColumn = aEnd.fEndColumn;
}
}

• class PCode:
package ast;

import parser.Token;

public abstract class PCode extends Position


{
public PCode( Token aInstruction )
{
super( aInstruction );
}

public PCode( Token aInstruction, Position aEnd )


{
super( aInstruction, aEnd );
}

public PCode( Token aStart, Token aEnd )


{
super( aStart, aEnd );
}

public abstract String toString();


}

for PCode instructions

5
COS30023 Semester 2, 2019 Dr. Markus Lumpe

• class PCodeArgument:
package ast;

import parser.Token;

public abstract class PCodeArgument extends Position


{
public PCodeArgument( Token aToken )
{
super( aToken );
}

public PCodeArgument( Token aStart, Token aEnd )


{
super( aStart, aEnd );
}

public abstract String toString();


}

for floating point (à la problem set 4) and variable arguments.

Test output:

PCode accepted:
load 4.0
load 2.0
mul
dup
print "4 * 2 = "
load 1.0
add
dup
print "4 * 2 + 1 = "
store $x

Das könnte Ihnen auch gefallen