📄 parser.java
字号:
/* * @(#)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 + -