diff options
Diffstat (limited to 'src/experimental/parser.h')
| -rw-r--r-- | src/experimental/parser.h | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/src/experimental/parser.h b/src/experimental/parser.h new file mode 100644 index 0000000..a168c7b --- /dev/null +++ b/src/experimental/parser.h | |||
| @@ -0,0 +1,135 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2007-2011 Xagasoft, All rights reserved. | ||
| 3 | * | ||
| 4 | * This file is part of the libbu++ library and is released under the | ||
| 5 | * terms of the license contained in the file LICENSE. | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef BU_PARSER_H | ||
| 9 | #define BU_PARSER_H | ||
| 10 | |||
| 11 | #include "bu/string.h" | ||
| 12 | #include "bu/list.h" | ||
| 13 | #include "bu/array.h" | ||
| 14 | #include "bu/hash.h" | ||
| 15 | #include "bu/signals.h" | ||
| 16 | |||
| 17 | #include "bu/lexer.h" | ||
| 18 | |||
| 19 | namespace Bu | ||
| 20 | { | ||
| 21 | /** | ||
| 22 | * The base framework for a LR(1) grammar parser. Provided a proper set of | ||
| 23 | * ParserStates this will prase any input the lexer can provide. | ||
| 24 | */ | ||
| 25 | class Parser | ||
| 26 | { | ||
| 27 | public: | ||
| 28 | Parser(); | ||
| 29 | virtual ~Parser(); | ||
| 30 | |||
| 31 | /** | ||
| 32 | * When a Lexer is pushed onto the stack it becomes the source for | ||
| 33 | * future tokens read by the parser until it is popped off the stack. | ||
| 34 | * The Parser takes ownership of every Lexer pushed onto the stack, | ||
| 35 | * and will delete it when it is popped off the stack. | ||
| 36 | */ | ||
| 37 | void pushLexer( Lexer *pLex ); | ||
| 38 | |||
| 39 | /** | ||
| 40 | * Pop a lexer off the stack, and delete it. | ||
| 41 | */ | ||
| 42 | void popLexer(); | ||
| 43 | |||
| 44 | Lexer::Token *popToken(); | ||
| 45 | void pushToken( Lexer::Token *pTok ); | ||
| 46 | |||
| 47 | /** | ||
| 48 | * Execute a parse. | ||
| 49 | */ | ||
| 50 | void parse(); | ||
| 51 | |||
| 52 | void setRootNonTerminal( int iRoot ); | ||
| 53 | void setRootNonTerminal( const Bu::String &sRoot ); | ||
| 54 | |||
| 55 | typedef Bu::Signal1<void, Parser &> Reduction; | ||
| 56 | |||
| 57 | /** | ||
| 58 | * Represents a possible state, either a terminal or non-terminal symbol | ||
| 59 | * in a Production. | ||
| 60 | */ | ||
| 61 | class State | ||
| 62 | { | ||
| 63 | public: | ||
| 64 | enum Type | ||
| 65 | { | ||
| 66 | typeTerminal, | ||
| 67 | typeTerminalPush, | ||
| 68 | typeNonTerminal, | ||
| 69 | typeReduction | ||
| 70 | }; | ||
| 71 | |||
| 72 | State( Type eType, int iIndex ); | ||
| 73 | virtual ~State(); | ||
| 74 | |||
| 75 | //private: | ||
| 76 | Type eType; | ||
| 77 | int iIndex; | ||
| 78 | }; | ||
| 79 | |||
| 80 | typedef Bu::List<State> Production; | ||
| 81 | |||
| 82 | class NonTerminal | ||
| 83 | { | ||
| 84 | public: | ||
| 85 | NonTerminal(); | ||
| 86 | virtual ~NonTerminal(); | ||
| 87 | |||
| 88 | void addProduction( Production p ); | ||
| 89 | void setCanSkip(); | ||
| 90 | |||
| 91 | // private: | ||
| 92 | typedef Bu::List<Production> ProductionList; | ||
| 93 | ProductionList lProduction; | ||
| 94 | bool bCanSkip; | ||
| 95 | }; | ||
| 96 | |||
| 97 | int addNonTerminal( const Bu::String &sName, NonTerminal &nt ); | ||
| 98 | int addNonTerminal( const Bu::String &sName ); | ||
| 99 | void setNonTerminal( const Bu::String &sName, NonTerminal &nt ); | ||
| 100 | int getNonTerminalId( const Bu::String &sName ); | ||
| 101 | bool hasNonTerminal( const Bu::String &sName ); | ||
| 102 | |||
| 103 | int addReduction( const Bu::String &sName, const Reduction &r ); | ||
| 104 | int addReduction( const Bu::String &sName ); | ||
| 105 | void setReduction( const Bu::String &sName, const Reduction &r ); | ||
| 106 | int getReductionId( const Bu::String &sName ); | ||
| 107 | bool hasReduction( const Bu::String &sName ); | ||
| 108 | |||
| 109 | private: | ||
| 110 | bool selectProduction( int iNt, Lexer::Token *ptCur ); | ||
| 111 | void advanceState(); | ||
| 112 | |||
| 113 | private: | ||
| 114 | typedef Bu::List<Lexer *> LexerStack; | ||
| 115 | typedef Bu::List<Lexer::Token *> TokenStack; | ||
| 116 | typedef Bu::List<Production::const_iterator> StateStack; | ||
| 117 | typedef Bu::Array<Reduction> ReductionArray; | ||
| 118 | typedef Bu::Hash<Bu::String,int> NameIndexHash; | ||
| 119 | typedef Bu::Array<NonTerminal> NonTerminalArray; | ||
| 120 | |||
| 121 | LexerStack sLexer; | ||
| 122 | TokenStack sToken; | ||
| 123 | StateStack sState; | ||
| 124 | ReductionArray aReduction; | ||
| 125 | NameIndexHash hReductionName; | ||
| 126 | NonTerminalArray aNonTerminal; | ||
| 127 | NameIndexHash hNonTerminalName; | ||
| 128 | int iRootNonTerminal; | ||
| 129 | }; | ||
| 130 | Bu::Formatter &operator<<( Bu::Formatter &f, Bu::Parser::State::Type t ); | ||
| 131 | Bu::Formatter &operator<<( Bu::Formatter &f, const Bu::Parser::State &s ); | ||
| 132 | }; | ||
| 133 | |||
| 134 | |||
| 135 | #endif | ||
