Mork Banner
Home
Small example
Large example
Tools
Links
Misc
Contributions
Download ChangeLog Mailing list Manual Sourceforge Feedback

Large example

Here's an interpreter for a language with boolean, integer and string variables, plus various expressions and statements. It's realized by a grammar file, a mapper file and various Java files. Compile the interpreter and run a sample script as follows:

  cd /foo/examples/interpreter
  javac *.java
  mork Mapper.map
  java interpreter.Main tests/fak.script

script.grm

[PARSER]

Script          ::= "script" Declarations Block;

Declarations    ::= ( Variable ";" )* ;
Variable        ::= Type Identifier ;
Type            ::= "bool" | "int" ;
Type            ::= "string" ;

Stmt            ::= Block | Print | Input | If | While | Assign ;

Block           ::= "{" Stmt* "}";
Print           ::= "print" Expr ";";
Input           ::= "input" Reference ";";
If              ::= "if" "(" Expr ")" Block ("else" Block )? ;
While           ::= "while" "(" Expr ")" Stmt ;
Assign          ::= Reference "=" Expr ";";

Expr            ::= Or | And ;
Or              ::= Expr "||" And ;

And             ::= And2 | Equation ;
And2            ::= And "&&" Equation ;

Equation        ::= Equation2 | Relation ;
Equation2       ::= Equation ("==" | "!=") Relation ;

Relation        ::= Relation2 | Sum ;
Relation2       ::= Relation ("<" | ">" | "<=" | ">=") Sum ;

Sum             ::= Sum2 | Prod  ;
Sum2            ::= Sum ("+"|"-") Prod ;
Prod            ::= Prod2 | Unary ;
Prod2           ::= Prod ("*"|"/"|"%") Unary ;
Unary           ::= Unary1 | Atom ;
Unary1          ::= ("+"|"-"|"!") Unary;

Atom            ::= Const | Reference | "(" Expr ")";
Reference       ::= Identifier ;

Const           ::= String | Integer | Boolean ;
Boolean         ::= "true" | "false" ;


[SCANNER]
    white = Space, Comment;

String     ::= '"' '"'!* '"' ;
Integer    ::= Digit+ ;
Identifier ::= Letter (Letter | Digit | '_')* ;
Letter     ::= 'A'..'Z' | 'a'..'z' ;
Digit      ::= '0'..'9';

Space      ::= (' ' | '\b' | '\t' | '\n' | '\f' | '\r' )+ ;
Comment    ::= '#' ('\n'|'\r')!* ;



Mapper.map

mapper interpreter.Mapper;

grm = "script.grm";

import interpreter:
    Assign, Binary, Block, Const, Declarations, Expression, If, Input,
    Print, Reference, Script, Unary, Variable, While;
import de.mlhartme.mork.semantics:
    BuiltIn;
import java.lang:
    Boolean, Integer, String;

Script              => Script;
Declarations        => Declarations : >\\Script  > \\Script//Reference;
Variable            => Variable;
"int"               => Expression.INT;
"bool"              => Expression.BOOL;
"string"            => Expression.STR;

# Statements
Block               => Block;
While               => While;
If                  => If;
Input               => Input;
Print               => Print;
Assign              => Assign;

# Expressions
Const               => Const;
Reference           => Reference;
Or                  => Binary;
And2                => Binary;
Equation2           => Binary;
Relation2           => Binary;
Sum2                => Binary;
Prod2               => Binary;
Unary1              => Unary;

# Operators
"+"                 => Expression.ADD;
"-"                 => Expression.SUB;
"*"                 => Expression.MUL;
"/"                 => Expression.DIV;
"%"                 => Expression.REM;
"&&"                => Expression.AND;
"||"                => Expression.OR;
"!"                 => Expression.NOT;
"=="                => Expression.EQ;
"!="                => Expression.NE;
"<"                 => Expression.LT;
">"                 => Expression.GT;
"<="                => Expression.LE;
">="                => Expression.GE;

# misc
Boolean             => Boolean;
"true"              => Boolean.TRUE;
"false"             => Boolean.FALSE;
Identifier          => String;
                    => [text]: > Identifier;
String              => BuiltIn.parseString;
                    => [text]: > String;
Integer             => Integer.parseInt;
                    => [text]: > Integer;



Java files

The Java files are listed here.

The kick-off code is in Main.java, the other classes resemble a kind of abstract syntax. Running the interpreter instantiates a script object and invokes the run method on it.

Compare this example with interpreter examples based on JavaCC/jjTree or SableCC: Mork maps a script file to user-defined classes instead of generated classes. These classes implement the necessary computations by using the appropriate OO features. There is no need for tree-walks, visitor classes or similar stuff that is necessary to add computations to generated classes. The mapper file separates syntax and computations (i.e. classes), making both of them reusable.


Last modified: Fri Mar 29 20:48:06 2002.

Copyright © 2002 Michael Hartmeier.

Hosted at SourceForge.net Logo