<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">import java.util.ArrayList;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.FileWriter;

/**
 * An example parser for a Simple language.
 * 
 * For CS 212, Sep 2007.
 * 
 * The grammar for the Simple language is shown below.  
 * '*' indicates 0 or more occurrences; '|' indicates choice; an item within 
 * brackets [] is optional; parentheses () are used for grouping.  
 * '*' and parentheses also appears as a token of the language, but
 * this usage should be clear from context.
 *   program -&gt; statement* end .
 *   statement -&gt; name = expression ;
 *   statement -&gt; do expression : statement* end ;
 *   expression -&gt; part [(+|-|*|/) part]
 *   part -&gt; name | number | (expression) 
 *   name -&gt; x|y|z
 * 
 * @author Paul Chew
 */
public class SimpleParser {
    
    Scanner212 scanner;            // The scanner
    
    /**
     * @param scanner the scanner to be used during parsing
     */
    public SimpleParser (Scanner212 scanner) {
        this.scanner = scanner;
    }
    
    /**
     * Test program.
     */
    public static void main (String[] args) throws IOException {
        // Prepare a file for input
        String fileName = "test.txt";
        if (args.length == 1) fileName = args[0];
        FileReader f = new FileReader(fileName);
        // Prepare the scanner
        Scanner212 scanner = Scanner212.baliScanner();
        scanner.setSource(f);
        scanner.advance();
        // Build the AST and display it
        SimpleAST tree = (new SimpleParser(scanner)).parseProgram();
        System.out.println(tree);
        // Generate code
        PrintWriter out = new PrintWriter(new FileWriter("try.sam"));
        tree.generate(out);
        // Clean up
        f.close();  out.close();
    }
    
    public SimpleAST parseProgram () {
        ArrayList&lt;SimpleAST&gt; statements = new ArrayList&lt;SimpleAST&gt;();
        while (!scanner.matches("end")) {
            statements.add(parseStatement());
        }
        eat("end"); eat(".");
        return new ProgramNode(statements);
    }
    
    public SimpleAST parseStatement () {
        if (scanner.matches("do")) {
            // Do statement
            eat("do");
            SimpleAST expression = parseExpression();
            eat(":");
            ArrayList&lt;SimpleAST&gt; statements = new ArrayList&lt;SimpleAST&gt;();
            while (!scanner.matches("end")) {
                statements.add(parseStatement());
            }
            eat("end"); eat(";");
            return new DoNode(expression, statements);
        } else {
            // Assignment statement
            String target = scanner.token();
            if (target.length() == 1 &amp;&amp; "xyz".contains(target)) scanner.advance();
            else throw new ParseError("Expected a target, not " + target);
            eat("=");
            SimpleAST expression = parseExpression();
            eat(";");
            return new AssignmentNode(target, expression);
        }
    }
    
    public SimpleAST parseExpression () {
        SimpleAST left = parsePart();
        String token = scanner.token();
        if (token.length() == 1 &amp;&amp; "+-*/".contains(token)) {
            scanner.advance();
            SimpleAST right = parsePart();
            return new OperatorNode(token, left, right);
        } else {
            return left;
        }
    }
    
    public SimpleAST parsePart () {
        if (scanner.kind() == 'i') {
            int value = Integer.valueOf(scanner.token());
            scanner.advance();
            return new NumberNode(value);
        } else if (scanner.matches("(")) {
            // Parenthesized expression
            eat("(");
            SimpleAST expression = parseExpression();
            eat(")");
            return expression;
        } else return parseName();
    }
    
    public SimpleAST parseName () {
        String variable = scanner.token();
        if (variable.length() == 1 &amp;&amp; "xyz".contains(variable)) {
            scanner.advance();
            return new VariableNode(variable);
        }
        throw new ParseError("Expected a name, not " + variable);
    }
    
    public void eat (String target) {
        if (scanner.matches(target)) scanner.advance();
        else throw new ParseError("Expected " + target + ", not " + scanner.token());
    }
}

/**
 * Parsing error.
 */
class ParseError extends RuntimeException {
    public ParseError (String string) {
        super(string);
    }
}

    </pre></body></html>