⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.java

📁 The triangle language processor will be consist of a compiler, an interpreter, and a disassembler
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * @(#)Parser.java                        2.1 2003/10/07 * * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland * and School of Computer and Math Sciences, The Robert Gordon University, * St. Andrew Street, Aberdeen AB25 1HG, Scotland. * All rights reserved. * * This software is provided free for educational use only. It may * not be used for commercial purposes without the prior written permission * of the authors. */package Triangle.SyntacticAnalyzer;import Triangle.ErrorReporter;import Triangle.AbstractSyntaxTrees.ActualParameter;import Triangle.AbstractSyntaxTrees.ActualParameterSequence;import Triangle.AbstractSyntaxTrees.ArrayAggregate;import Triangle.AbstractSyntaxTrees.ArrayExpression;import Triangle.AbstractSyntaxTrees.ArrayTypeDenoter;import Triangle.AbstractSyntaxTrees.AssignCommand;import Triangle.AbstractSyntaxTrees.BinaryExpression;import Triangle.AbstractSyntaxTrees.CallCommand;import Triangle.AbstractSyntaxTrees.CallExpression;import Triangle.AbstractSyntaxTrees.CharacterExpression;import Triangle.AbstractSyntaxTrees.CharacterLiteral;import Triangle.AbstractSyntaxTrees.Command;import Triangle.AbstractSyntaxTrees.ConstActualParameter;import Triangle.AbstractSyntaxTrees.ConstDeclaration;import Triangle.AbstractSyntaxTrees.ConstFormalParameter;import Triangle.AbstractSyntaxTrees.Declaration;import Triangle.AbstractSyntaxTrees.DotVname;import Triangle.AbstractSyntaxTrees.EmptyActualParameterSequence;import Triangle.AbstractSyntaxTrees.EmptyCommand;import Triangle.AbstractSyntaxTrees.EmptyFormalParameterSequence;import Triangle.AbstractSyntaxTrees.Expression;import Triangle.AbstractSyntaxTrees.FieldTypeDenoter;import Triangle.AbstractSyntaxTrees.FormalParameter;import Triangle.AbstractSyntaxTrees.FormalParameterSequence;import Triangle.AbstractSyntaxTrees.FuncActualParameter;import Triangle.AbstractSyntaxTrees.FuncDeclaration;import Triangle.AbstractSyntaxTrees.FuncFormalParameter;import Triangle.AbstractSyntaxTrees.Identifier;import Triangle.AbstractSyntaxTrees.IfCommand;import Triangle.AbstractSyntaxTrees.IfExpression;import Triangle.AbstractSyntaxTrees.IntegerExpression;import Triangle.AbstractSyntaxTrees.IntegerLiteral;import Triangle.AbstractSyntaxTrees.LetCommand;import Triangle.AbstractSyntaxTrees.LetExpression;import Triangle.AbstractSyntaxTrees.MultipleActualParameterSequence;import Triangle.AbstractSyntaxTrees.MultipleArrayAggregate;import Triangle.AbstractSyntaxTrees.MultipleFieldTypeDenoter;import Triangle.AbstractSyntaxTrees.MultipleFormalParameterSequence;import Triangle.AbstractSyntaxTrees.MultipleRecordAggregate;import Triangle.AbstractSyntaxTrees.Operator;import Triangle.AbstractSyntaxTrees.ProcActualParameter;import Triangle.AbstractSyntaxTrees.ProcDeclaration;import Triangle.AbstractSyntaxTrees.ProcFormalParameter;import Triangle.AbstractSyntaxTrees.Program;import Triangle.AbstractSyntaxTrees.RecordAggregate;import Triangle.AbstractSyntaxTrees.RecordExpression;import Triangle.AbstractSyntaxTrees.RecordTypeDenoter;import Triangle.AbstractSyntaxTrees.SequentialCommand;import Triangle.AbstractSyntaxTrees.SequentialDeclaration;import Triangle.AbstractSyntaxTrees.SimpleTypeDenoter;import Triangle.AbstractSyntaxTrees.SimpleVname;import Triangle.AbstractSyntaxTrees.SingleActualParameterSequence;import Triangle.AbstractSyntaxTrees.SingleArrayAggregate;import Triangle.AbstractSyntaxTrees.SingleFieldTypeDenoter;import Triangle.AbstractSyntaxTrees.SingleFormalParameterSequence;import Triangle.AbstractSyntaxTrees.SingleRecordAggregate;import Triangle.AbstractSyntaxTrees.SubscriptVname;import Triangle.AbstractSyntaxTrees.TypeDeclaration;import Triangle.AbstractSyntaxTrees.TypeDenoter;import Triangle.AbstractSyntaxTrees.UnaryExpression;import Triangle.AbstractSyntaxTrees.VarActualParameter;import Triangle.AbstractSyntaxTrees.VarDeclaration;import Triangle.AbstractSyntaxTrees.VarFormalParameter;import Triangle.AbstractSyntaxTrees.Vname;import Triangle.AbstractSyntaxTrees.VnameExpression;import Triangle.AbstractSyntaxTrees.WhileCommand;public class Parser {  private Scanner lexicalAnalyser;  private ErrorReporter errorReporter;  private Token currentToken;  private SourcePosition previousTokenPosition;  public Parser(Scanner lexer, ErrorReporter reporter) {    lexicalAnalyser = lexer;    errorReporter = reporter;    previousTokenPosition = new SourcePosition();  }// accept checks whether the current token matches tokenExpected.// If so, fetches the next token.// If not, reports a syntactic error.  void accept (int tokenExpected) throws SyntaxError {    if (currentToken.kind == tokenExpected) {      previousTokenPosition = currentToken.position;      currentToken = lexicalAnalyser.scan();    } else {      syntacticError("\"%\" expected here", Token.spell(tokenExpected));    }  }  void acceptIt() {    previousTokenPosition = currentToken.position;    currentToken = lexicalAnalyser.scan();  }// start records the position of the start of a phrase.// This is defined to be the position of the first// character of the first token of the phrase.  void start(SourcePosition position) {    position.start = currentToken.position.start;  }// finish records the position of the end of a phrase.// This is defined to be the position of the last// character of the last token of the phrase.  void finish(SourcePosition position) {    position.finish = previousTokenPosition.finish;  }  void syntacticError(String messageTemplate, String tokenQuoted) throws SyntaxError {    SourcePosition pos = currentToken.position;    errorReporter.reportError(messageTemplate, tokenQuoted, pos);    throw(new SyntaxError());  }/////////////////////////////////////////////////////////////////////////////////// PROGRAMS/////////////////////////////////////////////////////////////////////////////////  public Program parseProgram() {    Program programAST = null;    previousTokenPosition.start = 0;    previousTokenPosition.finish = 0;    currentToken = lexicalAnalyser.scan();    try {      Command cAST = parseCommand();      programAST = new Program(cAST, previousTokenPosition);      if (currentToken.kind != Token.EOT) {        syntacticError("\"%\" not expected after end of program",          currentToken.spelling);      }    }    catch (SyntaxError s) { return null; }    return programAST;  }/////////////////////////////////////////////////////////////////////////////////// LITERALS/////////////////////////////////////////////////////////////////////////////////// parseIntegerLiteral parses an integer-literal, and constructs// a leaf AST to represent it.  IntegerLiteral parseIntegerLiteral() throws SyntaxError {    IntegerLiteral IL = null;    if (currentToken.kind == Token.INTLITERAL) {      previousTokenPosition = currentToken.position;      String spelling = currentToken.spelling;      IL = new IntegerLiteral(spelling, previousTokenPosition);      currentToken = lexicalAnalyser.scan();    } else {      IL = null;      syntacticError("integer literal expected here", "");    }    return IL;  }// parseCharacterLiteral parses a character-literal, and constructs a leaf// AST to represent it.  CharacterLiteral parseCharacterLiteral() throws SyntaxError {    CharacterLiteral CL = null;    if (currentToken.kind == Token.CHARLITERAL) {      previousTokenPosition = currentToken.position;      String spelling = currentToken.spelling;      CL = new CharacterLiteral(spelling, previousTokenPosition);      currentToken = lexicalAnalyser.scan();    } else {      CL = null;      syntacticError("character literal expected here", "");    }    return CL;  }// parseIdentifier parses an identifier, and constructs a leaf AST to// represent it.  Identifier parseIdentifier() throws SyntaxError {    Identifier I = null;    if (currentToken.kind == Token.IDENTIFIER) {      previousTokenPosition = currentToken.position;      String spelling = currentToken.spelling;      I = new Identifier(spelling, previousTokenPosition);      currentToken = lexicalAnalyser.scan();    } else {      I = null;      syntacticError("identifier expected here", "");    }    return I;  }// parseOperator parses an operator, and constructs a leaf AST to// represent it.  Operator parseOperator() throws SyntaxError {    Operator O = null;    if (currentToken.kind == Token.OPERATOR) {      previousTokenPosition = currentToken.position;      String spelling = currentToken.spelling;      O = new Operator(spelling, previousTokenPosition);      currentToken = lexicalAnalyser.scan();    } else {      O = null;      syntacticError("operator expected here", "");    }    return O;  }/////////////////////////////////////////////////////////////////////////////////// COMMANDS/////////////////////////////////////////////////////////////////////////////////// parseCommand parses the command, and constructs an AST// to represent its phrase structure.  Command parseCommand() throws SyntaxError {    Command commandAST = null; // in case there's a syntactic error    SourcePosition commandPos = new SourcePosition();    start(commandPos);    commandAST = parseSingleCommand();    while (currentToken.kind == Token.SEMICOLON) {      acceptIt();      Command c2AST = parseSingleCommand();      finish(commandPos);      commandAST = new SequentialCommand(commandAST, c2AST, commandPos);    }    return commandAST;  }  Command parseSingleCommand() throws SyntaxError {    Command commandAST = null; // in case there's a syntactic error    SourcePosition commandPos = new SourcePosition();    start(commandPos);    switch (currentToken.kind) {    case Token.IDENTIFIER:      {        Identifier iAST = parseIdentifier();        if (currentToken.kind == Token.LPAREN) {          acceptIt();          ActualParameterSequence apsAST = parseActualParameterSequence();          accept(Token.RPAREN);          finish(commandPos);          commandAST = new CallCommand(iAST, apsAST, commandPos);        } else {          Vname vAST = parseRestOfVname(iAST);          accept(Token.BECOMES);          Expression eAST = parseExpression();          finish(commandPos);          commandAST = new AssignCommand(vAST, eAST, commandPos);        }      }      break;    case Token.BEGIN:      acceptIt();      commandAST = parseCommand();      accept(Token.END);      break;    case Token.LET:      {        acceptIt();        Declaration dAST = parseDeclaration();        accept(Token.IN);        Command cAST = parseSingleCommand();        finish(commandPos);        commandAST = new LetCommand(dAST, cAST, commandPos);      }      break;    case Token.IF:      {        acceptIt();        Expression eAST = parseExpression();        accept(Token.THEN);        Command c1AST = parseSingleCommand();        accept(Token.ELSE);        Command c2AST = parseSingleCommand();        finish(commandPos);        commandAST = new IfCommand(eAST, c1AST, c2AST, commandPos);      }      break;    case Token.WHILE:      {        acceptIt();        Expression eAST = parseExpression();        accept(Token.DO);        Command cAST = parseSingleCommand();        finish(commandPos);        commandAST = new WhileCommand(eAST, cAST, commandPos);      }      break;    case Token.SEMICOLON:    case Token.END:    case Token.ELSE:    case Token.IN:    case Token.EOT:      finish(commandPos);      commandAST = new EmptyCommand(commandPos);      break;    default:      syntacticError("\"%\" cannot start a command",        currentToken.spelling);      break;    }    return commandAST;  }/////////////////////////////////////////////////////////////////////////////////// EXPRESSIONS/////////////////////////////////////////////////////////////////////////////////  Expression parseExpression() throws SyntaxError {    Expression expressionAST = null; // in case there's a syntactic error    SourcePosition expressionPos = new SourcePosition();    start (expressionPos);    switch (currentToken.kind) {    case Token.LET:      {        acceptIt();        Declaration dAST = parseDeclaration();        accept(Token.IN);        Expression eAST = parseExpression();        finish(expressionPos);        expressionAST = new LetExpression(dAST, eAST, expressionPos);      }      break;    case Token.IF:      {        acceptIt();        Expression e1AST = parseExpression();        accept(Token.THEN);        Expression e2AST = parseExpression();        accept(Token.ELSE);        Expression e3AST = parseExpression();        finish(expressionPos);        expressionAST = new IfExpression(e1AST, e2AST, e3AST, expressionPos);      }      break;    default:      expressionAST = parseSecondaryExpression();      break;    }    return expressionAST;  }  Expression parseSecondaryExpression() throws SyntaxError {    Expression expressionAST = null; // in case there's a syntactic error    SourcePosition expressionPos = new SourcePosition();    start(expressionPos);    expressionAST = parsePrimaryExpression();    while (currentToken.kind == Token.OPERATOR) {      Operator opAST = parseOperator();      Expression e2AST = parsePrimaryExpression();      expressionAST = new BinaryExpression (expressionAST, opAST, e2AST,        expressionPos);    }    return expressionAST;  }  Expression parsePrimaryExpression() throws SyntaxError {    Expression expressionAST = null; // in case there's a syntactic error    SourcePosition expressionPos = new SourcePosition();    start(expressionPos);    switch (currentToken.kind) {    case Token.INTLITERAL:      {        IntegerLiteral ilAST = parseIntegerLiteral();        finish(expressionPos);        expressionAST = new IntegerExpression(ilAST, expressionPos);      }      break;    case Token.CHARLITERAL:      {        CharacterLiteral clAST= parseCharacterLiteral();        finish(expressionPos);        expressionAST = new CharacterExpression(clAST, expressionPos);      }      break;    case Token.LBRACKET:      {        acceptIt();        ArrayAggregate aaAST = parseArrayAggregate();        accept(Token.RBRACKET);        finish(expressionPos);        expressionAST = new ArrayExpression(aaAST, expressionPos);      }      break;    case Token.LCURLY:      {        acceptIt();        RecordAggregate raAST = parseRecordAggregate();        accept(Token.RCURLY);        finish(expressionPos);        expressionAST = new RecordExpression(raAST, expressionPos);      }      break;    case Token.IDENTIFIER:      {        Identifier iAST= parseIdentifier();        if (currentToken.kind == Token.LPAREN) {          acceptIt();          ActualParameterSequence apsAST = parseActualParameterSequence();          accept(Token.RPAREN);          finish(expressionPos);          expressionAST = new CallExpression(iAST, apsAST, expressionPos);        } else {          Vname vAST = parseRestOfVname(iAST);          finish(expressionPos);          expressionAST = new VnameExpression(vAST, expressionPos);        }      }      break;    case Token.OPERATOR:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -