/* ----------------------------------------------------------------------------- This source file is part of OGRE (Object-oriented Graphics Rendering Engine) For the latest info, see http://www.stevestreeting.com/ogre/ Copyright (c) 2000-2005 The OGRE Team Also see acknowledgements in Readme.html This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/gpl.html. ----------------------------------------------------------------------------- */ #ifndef __Compiler2Pass_H__ #define __Compiler2Pass_H__ #include #include "OgrePrerequisites.h" namespace Ogre { /** Compiler2Pass is a generic 2 pass compiler/assembler @remarks provides a tokenizer in pass 1 and relies on the subclass to provide the virtual method for pass 2 PASS 1 - tokenize source: this is a simple brute force lexical scanner/analyzer that also parses the formed token for proper semantics and context in one pass it uses top down (recursive descent) ruling based on Backus - Naur Form (BNF) notation for semantic checking. During Pass1, if a terminal token is identified as having an action then that action gets triggered when the next terminal token is uncountered that has an action. PASS 2 - generate application specific instructions ie native instructions based on the tokens in the instruction container. @par this class must be subclassed with the subclass providing some implementation details for Pass 2. The subclass is responsible for setting up the token libraries along with defining the language syntax and handling token actions during the second pass. @par The sub class normally supplies a simplified BNF text description in its constructor prior to doing any parsing/tokenizing of source. The simplified BNF text description defines the language syntax and rule structure. The meta-symbols used in the BNF text description are: @par ::= meaning "is defined as". "::=" starts the definition of a rule. The left side of ::= must contain an @par <> angle brackets are used to surround syntax rule names. A syntax rule name is also called a non-terminal in that it does not generate a terminal token in the instruction container for pass 2 processing. @par | meaning "or". if the item on the left of the | fails then the item on the right is tested. Example: ::= 'true' | 'false'; whitespace is used to imply AND operation between left and right items. Example: ::= 'terrain_shadows' the 'terrain_shadows' terminal token must be found and rule must pass in order for rule to pass. @par [] optional rule identifier is enclosed in meta symbols [ and ]. Note that only one identifier or terminal token can take [] modifier. @par {} repetitive identifier (zero or more times) is enclosed in meta symbols { and } Note that only one identifier or terminal token can take {} modifier. @par '' terminal tokens are surrounded by single quotes. A terminal token is always one or more characters. For example: 'Colour' defines a character sequence that must be matched in whole. Note that matching is case sensitive. @par @ turn on single character scanning and don't skip white space. Mainly used for label processing that allow white space. Example: '@ ' prevents the white space between the quotes from being skipped @par -'' no terminal token is generated when a - precedes the first single quote but the text in between the quotes is still tested against the characters in the source being parsed. @par (?! ) negative lookahead (not test) inspired by Perl 5. Scans ahead for a non-terminal or terminal expression that should fail in order to make the rule production pass. Does not generate a token or advance the cursur. If the lookahead result fails ie token is found, then the current rule fails and rollback occurs. Mainly used to solve multiple contexts of a token. An Example of where not test is used to solve multiple contexts: ::= "::=" \n ::= { }\n ::= "|" \n ::= { }\n ::= | | | \n ::= (?!"::=") appears on both sides of the ::= so (?!"::=") test to make sure that ::= is not on the right which would indicate that a new rule was being formed. Works on both terminals and non-terminals. Note: lookahead failure causes the whole rule to fail and rollback to occur @par <#name> # indicates that a numerical value is to be parsed to form a terminal token. Name is optional and is just a descriptor to help with understanding what the value will be used for. Example: ::= <#red> <#green> <#blue> @par () parentheses enclose a set of characters that can be used to generate a user identifier. for example: (0123456789) matches a single character found in that set. An example of a user identifier: @par