<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.IOException;
import edu.cornell.cs.sam.io.SamTokenizer;
import edu.cornell.cs.sam.io.Tokenizer.TokenType;

/**
 * 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 {
    
    SamTokenizer scanner;            // The scanner
    
    /**
     * Test program.
     */
    public static void main (String[] args) throws IOException {
        SimpleParser parser = new SimpleParser();
        String fileName = "test.txt";
        if (args.length == 1) fileName = args[0];
        SimpleAST tree = parser.parse(fileName);
        System.out.println(tree);
    }
    
    /**
     * Parse the specified file, producing an AST.
     * @param fileName the file to be parsed.
     */
    public SimpleAST parse (String fileName) throws IOException {
        scanner = new SamTokenizer(fileName);
        SimpleAST tree = parseProgram();
        scanner.close();           // Clean up
        return tree;
    }
    
    public SimpleAST parseProgram () {
        ArrayList&lt;SimpleAST&gt; statements = new ArrayList&lt;SimpleAST&gt;();
        while (!scanner.test("end")) {
            statements.add(parseStatement());
        }
        scanner.match("end"); scanner.match('.');
        return new ProgramNode(statements);
    }
    
    public SimpleAST parseStatement () {
        if (scanner.test("do")) {
            // Do statement
            scanner.match("do");
            SimpleAST expression = parseExpression();
            scanner.match(':');
            ArrayList&lt;SimpleAST&gt; statements = new ArrayList&lt;SimpleAST&gt;();
            while (!scanner.test("end")) {
                statements.add(parseStatement());
            }
            scanner.match("end"); scanner.match(';');
            return new DoNode(expression, statements);
        } else {
            // Assignment statement
            SimpleAST target = parseName();
            scanner.match('=');
            SimpleAST expression = parseExpression();
            scanner.match(';');
            return new AssignmentNode(target, expression);
        }
    }
    
    public SimpleAST parseExpression () {
        SimpleAST left = parsePart();
        if (scanner.test('+') || scanner.test('-') || 
            scanner.test('*') || scanner.test('/')) {
            String op = Character.toString(scanner.getOp());
            SimpleAST right = parsePart();
            return new OperatorNode(op, left, right);
        } else {
            return left;
        }
    }
    
    public SimpleAST parsePart () {
        if (scanner.peekAtKind() == TokenType.INTEGER) {
            return new NumberNode(scanner.getInt());
        } else if (scanner.test('(')) {
            // Parenthesized expression
            scanner.match('(');
            SimpleAST expression = parseExpression();
            scanner.match(')');
            return expression;
        } else return parseName();
    }
    
    public SimpleAST parseName () {
        String variable = scanner.getWord();
        if (variable.length() == 1 &amp;&amp; "xyz".contains(variable))
            return new VariableNode(variable);
        throw new ParseError("Expected a name, not " + variable);
    }
}

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

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