causerieIntroduction Units Class Hierarchy Classes, Interfaces, Objects and Records Types Variables Constants Functions and Procedures Identifiers Classes hierarchy graph
|
Class AParser
Unit
parsing
Declaration
type AParser = class(ANode)
Description
This class represents a generic parser. You will likely not construct an instance of this class directly since it only provides the support mechanisms needed for a parser and lacks the code to do the actual parsing.
When constructing a parser, you are expected to provide:
The parser will create and dispose of its own scanner while parsing.
Parsers descend from ANode because they are designed to be chained together: the top-level (program) parser will construct a block-level parser, which will itself construct a block-level or statement-level parser, which will construct an expression parser – and so on down the line. The advantages of this approach include readability – no long chain of case statements – and flexibility: new additions to the language usually require only the addition of a new type of statement- or expression-level parser.
Each time a higher-level parser constructs a lower-level parser, the new parser is linked to the Child property. The most recent lower-level parser created by a given parser can be obtained by calling AParser.CurrentElement.
Note that, although instances of AParser descend from ANode, they do not implement any of the streaming behavior for obvious reasons.
Hierarchy
Overview
Fields
Methods
Description
Fields
|
MyScanner: AScanner; |
Refers to the scanner used to tokenize the source
|
|
MyLog: ALog; |
Refers to the log used for parser output
|
|
MySource: AStream; |
Refers to the source stream being parsed
|
|
MyTokens: ATokenList; |
Refers to the list of tokens parsed from the source
|
Methods
|
constructor forSource(const ThisSource: AStream; const ThisLog: ALog); virtual; overload; |
Construct a new parser that will parse the specified source and output status and error messages to the specified log.
Both ThisSource and ThisLog must be valid instances of their respective classes in order for AParser.parse to succeed.
|
|
constructor forSource(const ThisParent: AParser); virtual; overload; |
Construct a new parser that will inherit the properties of its parent parser.
The new parser will inherit the values of ThisParent 's Scanner, Source and Log.
|
|
function init: boolean; override; |
Initializer
|
|
destructor destroy; override; |
Destroy the parser instance.
If Self.Parent is Nil , then that indicates this is a top-level parser, and so this method will free the token list and scanner associated with the parser, if any, before calling the inherited routine.
Otherwise, this method first pops its current token and pushes it back into the parent's list, so that the parent has the token which ended the program element. Then it nils the related properties so they are not freed (since the parent will still be using them) before calling the inherited routine.
|
|
function parse: int64; virtual; |
Parse the source.
The base definition of this method first checks to ensure that Self.Source, Self.Log, and Self.Tokens are all valid references (not Nil ). Descendant classes may call this routine before performing their own checks and parsing the specified source.
Returns
A negative value if an error has occurred before any parsing was done. This will most likely occur if either AParser.Source or AParser.Log are invalid (Nil ) pointers. A positive value indicates the number of non-fatal errors that occurred while parsing. A value of zero (0) indicates all is well. |
|
function parseUntilToken(const thisOpcode: TOpcode): int64; virtual; |
Parse statements until the specified opcode is reached.
This method may be called on to parse tokens or statements from the source until a specific keyword or delimiter is reached. It will most commonly be used to process function bodies, which are usually terminated by a keyword or delimiter of some kind.
Internally, this method simply loops by calling Self.parse and then checking the current token when that method returns. If the end of the stream is reached (and it is not the opcode desired), then this method will flag a fatal error.
When this method exits, Self.CurrentToken should refer to thisOpcode or to the end of the stream.
Returns
The total number of syntax errors that have occurred while parsing. This is the accumulated total from successive calls to Self.parse. Exceptions raised
- AParserFatalError
- if the end of the source stream is encountered before
thisOpcode is found – unless thisOpcode is TOKCAT_EOS.
|
|
function parseUntil(const ThisRule: ASyntaxRule): int64; overload; virtual; |
Parse until a token from the specified rule is encountered.
This method may be called to parse statements or tokens from the source until one of a number of opcodes is reached. It will most commonly be used to process loops, which are normally terminated by a keyword, delimiter, or expression.
Internally, this method simply loops by calling Self.parse and then checking the current token when that method returns. If the end of the stream is reached (and it is not part of the specified rule), then this method will flag a fatal error.
When this method exits, Self.CurrentToken should refer to a token from ThisRule or the end of the stream.
Returns
The total number of syntax errors that have occurred while parsing. This is the accumulated total from successive calls to Self.parse. Exceptions raised
- AParserFatalError
- if the end of the source stream is encountered before a token from
ThisRule is found – unless TOKCAT_EOS is part of ThisRule .
|
|
function CurrentToken: AToken; virtual; |
Retrieve a reference to the most recent token parsed from the source.
This method returns a reference to the last token in the token list maintained by the parser. This reference should NOT be freed by the caller; that will be done by the token list to which the token belongs.
If the caller wishes to pop a token from the token list, it should do so by calling ATokenList.Pop on AParser.Tokens. It is then responsible for freeing the token itself.
If Self.Tokens is Nil , this routine will construct a new instance of ATokenList to hold the tokens parsed by the parser. Additionally, after creating the new list, the routine checks to see if Self.Parent is not Nil ; if not, it means that that this parser was been created to parse a sub-element (such as a statement block or statement), and this method will push a copy of the previous token from its parent's list onto the new list, as well as the ACTUAL current token from the parent.
|
|
function PreviousToken: AToken; virtual; |
Retrieve a reference to the second-most-recent token parsed from the source.
This method returns a reference to the second-to-last token in the token list maintained by the parser. This reference should NOT be freed by the caller; that will be done by the token list to which the token belongs.
|
|
function PeekToken: AToken; virtual; |
Peek at the next token without advancing the current position in the source.
This method calls AScanner.Peek on the instance of AScanner maintained by the parser and returns the token reference to the caller. The caller is responsible for freeing that reference when it is no longer required.
|
|
function NextToken(const silenceCurrentToken: boolean = false): AToken; virtual; |
Retrieve the next token from the source.
This method calls AScanner.next on the instance of AScanner maintained by the paser and pushes the resulting token reference onto its list of tokens. That reference is then returned to the caller. The caller should NOT free it directly. Instead, they should pop the token from AParser.Tokens and then free the reference.
If silenceCurrentToken is True , then this method calls AToken.setSilenced on the current token before retrieving the next token from the source. Although AParser does not make use of this behavior, descendant classes may prevent silenced tokens from being output to their intermediate code streams.
|
|
function NextTokenIf(const condition: boolean; const silenceCurrentToken: boolean = false): AToken; virtual; |
Retrieve the next token from the source, but only if the specified condition is met.
This method is defined for convenience; it allows the programmer to specify a boolean expression, the outcome of which will determine whether another token is read from the source or not. If condition evaluates to True , then this method calls AParser.NextToken on Self ; otherwise it does nothing and returns Nil .
If silenceCurrentToken is True , then this method calls AToken.setSilenced on the current token before retrieving the next token from the source. Although AParser does not make use of this behavior, descendant classes may prevent silenced tokens from being output to their intermediate code streams.
|
|
procedure rewind; virtual; |
Return the current token to the source.
This method pops the last token from its token list and returns it to the source stream, so that it will be read again. If AParser.CurrentToken is Nil , then this routine does nothing.
|
|
procedure resyncToToken(const opcode: TOpcode); virtual; |
Resynchronize the parser to the specified opcode .
This method is designed to allow the parser to recover after a syntax error. If CurrentToken.opcode does not match opcode , it logs a syntax error to indicate that the current token is not expected, then calls AParser.skipToToken to skip tokens in the source.
|
|
procedure resyncTo(const ThisRule: ASyntaxRule); virtual; |
Resynchronize the parser to one of the tokens from the specified Rule .
This method is designed to allow the parser to recover after a syntax error. If CurrentToken.opcode is not found in ThisRule , it logs a syntax error to indicate that the current token is not expected, then calls AParser.skipTo to skip tokens in the source.
If ThisRule is Nil , then this routine does nothing.
|
|
procedure skipToToken(const opcode: TOpcode; const silenceInterveningTokens: boolean = true); virtual; |
Skip tokens in the source until one with the specified opcode is encountered.
If silenceInterveningTokens is True , then all tokens encountered before opcode will have their silenced property set by a call to AToken.setSilenced. Although AParser does not make use of this behavior, descendant classes may prevent silenced tokens from being written to their intermediate code streams.
Exceptions raised
- AParserFatalError
- if
opcode is not TOKCAT_EOS and the end of the source was reached before opcode was found.
|
|
procedure skipTo(const ThisRule: ASyntaxRule; const silenceInterveningTokens: boolean = true); virtual; |
Skip tokens until one of the tokens in ThisRule is encountered.
If ThisRule is Nil , then this method does nothing.
If silenceInterveningTokens is True , then all tokens encountered before opcode will have their silenced property set by a call to AToken.setSilenced. Although AParser does not make use of this behavior, descendant classes may prevent silenced tokens from being written to their intermediate code streams.
Exceptions raised
- AParserFatalError
- if
ThisRule does not contain TOKCAT_EOS and the end of the source is encountered before an opcode that is part of ThisRule .
|
|
procedure skipOverToken(const opcode: TOpcode; const silenceInterveningTokens: boolean = true); virtual; |
Skip over tokens in the source until one is encountered that does not match the specified opcode , or until the end of the stream is reached.
If silenceInterveningTokens is True , then all tokens encountered until one that is not opcode will have their silenced property set by a call to AToken.setSilenced. Although AParser does not make use of this behavior, descendant classes may prevent silenced tokens from being written to their intermediate code streams.
|
|
procedure skipOver(const ThisRule: ASyntaxRule; const silenceInterveningTokens: boolean = true); virtual; |
Skip over tokens in the source until one is encountered that is not part of ThisRule , or until the end of the stream is reached.
If ThisRule is Nil , then this method does nothing.
If silenceInterveningTokens is True , then all tokens encountered until one that is not opcode will have their silenced property set by a call to AToken.setSilenced. Although AParser does not make use of this behavior, descendant classes may prevent silenced tokens from being written to their intermediate code streams.
|
|
procedure note(const fmt: string; const params: array of const); virtual; |
Output a note to the log.
This method is defined for convenience; it automates the construction of an instance of AParserNote, then writes that instance to AParser.Log before freeing it.
fmt specifies the format of the message that will be written to the log. params specifies any values that should be incorporated into that message when it is logged.
|
|
procedure hint(const fmt: string; const params: array of const); virtual; |
Output a hint to the log.
This method is defined for convenience; it automates the construction of an instance of AParserHint, then writes that instance to AParser.Log before freeing it.
fmt specifies the format of the message that will be written to the log. params specifies any values that should be incorporated into that message when it is logged.
|
|
procedure warn(const fmt: string; const params: array of const); virtual; |
Output a warning to the log.
This method is defined for convenience; it automates the construction of an instance of AParserWarning, then writes that instance to AParser.Log before freeing it.
fmt specifies the format of the message that will be written to the log. params specifies any values that should be incorporated into that message when it is logged.
|
|
procedure syntaxError(const fmt: string; const params: array of const); virtual; |
Output a syntax error to the log.
This method is defined for convenience; it automates the construction of an instance of AParserSyntaxError, then writes that instance to AParser.Log before freeing it.
fmt specifies the format of the message that will be written to the log. params specifies any values that should be incorporated into that message when it is logged.
|
|
function fatalError(const fmt: string; const params: array of const): AParserFatalError; virtual; |
Output a fatal error to the log.
This method is defined for convenience; it automates the construction of an instance of AParserFatalError, then writes that instance to AParser.Log. The instance is returned to the caller, which allows the caller to both raise the fatal error and log it in one statement:
if MySource.hasEnded then
raise Self.fatalError('unexpected end of source', []);
If the caller does not intend to raise an exception with the returned instance, then it is responsible for freeing the instance when it is no longer required.
fmt specifies the format of the message that will be written to the log. params specifies any values that should be incorporated into that message when it is logged.
|
|
function Scanner: AScanner; virtual; |
Retrieve a reference to the scanner being used by the parser.
This value may be Nil until AParser.parse is called on the parser. In any event, the reference is managed by the parser and should NOT be freed by the caller.
|
|
function Log: ALog; virtual; |
Retrieve a reference to the log used by the parser for status and error output.
This reference should NOT be freed by the caller.
|
|
function Source: AStream; virtual; |
Retrieve a reference to the source stream being parsed by the parser.
This reference should NOT be freed by the caller.
|
|
function Tokens: ATokenList; virtual; |
Retrieve a reference to the list of tokens being managed by the parser.
This reference should NOT be freed by the caller; that will be done by the parser when it is, itself, freed.
|
|
function CurrentElement: AParser; virtual; |
Retrieve a reference to the most recent program element (a statement, statement block, expression) created by this parser for use in parsing the source. Calling this routine is functionally equivalent to casting the return value from AParser.Child to an instance of AParser.
This function may return Nil if the parser implementation does not make use of sub-parsers to process statements, statement blocks, or expressions.
|
|
function PreviousElement: AParser; virtual; |
Retrieve a reference to the second most recent program element (a statement, statement block, expression) created by this parser for use in parsing the source. Calling this routine is functionally equivalent to casting the return value from AParser.Previous, when called on AParser.CurrentElement, to an instance of AParser.
This function may return Nil if the parser implementation does not make use of sub-parsers to process statement, statement blocks, or expressions – or if the parser does not cache such program elements, but instead disposes of them as soon as they have done their work.
|
Generated by PasDoc 0.13.0 on 2015-01-10 17:13:18
|