public ParsingTableGenerationTests() { E = new NonTerminal("E"); T = new NonTerminal("T"); F = new NonTerminal("F"); tokenizer = new RegExpTokenizer(); tokenizer.SetTransitionFunction(new TableDrivenTransitionFunction()); id = tokenizer.UseTerminal(RegExp.GetNumberRegExp()); plus = tokenizer.UseTerminal(RegExp.Literal('+')); mult = tokenizer.UseTerminal(RegExp.Literal('*')); leftBrace = tokenizer.UseTerminal(RegExp.Literal('(')); rightBrace = tokenizer.UseTerminal(RegExp.Literal(')')); grammar = new AugmentedGrammar() { E --> E & plus & T, E --> T, T --> T & mult & F, T --> F, F --> leftBrace & E & rightBrace, F --> id }; }
/// <summary> /// Gets value of last terminal symbol provided. /// </summary> /// <param name="term">Terminal symbol used in the production rule.</param> /// <exception cref="ArgumentOutOfRangeException">Thrown in case there is no such token value.</exception> public Token this[Terminal term] { // TODO: Reverse order of popping tokens get { if (term == null) throw new ArgumentNullException("term"); if (mPoppedTokensCount < mPopableTokensCount) { int stackPeek = mTokens.Count - 1; // TODO: Check whether it's enough to reverse this loop for (int i = stackPeek; i >= 0; i--) { if (stackPeek - mPopableTokensCount == i) break; if (mTokens[i].Class == term.TokenClassID) { Token token = mTokens[i]; mTokens.RemoveAt(i); mPoppedTokensCount++; return token; } } } throw new ArgumentOutOfRangeException("term", "The terminal symbol " + term + " is not a part of the production."); } }
//TODO: Func<Token, bool> => Predicate<Token> public Terminal UseTerminal(RegExp regExp, Func<Token, bool> lexicalAction = null) { FiniteAutomata tokenNfa = GetTokenNfa(regExp); if (lexicalAction != null) { mLexicalActions[tokenNfa.Terminator.TokenClass] = lexicalAction; } AddTokenToNfa(tokenNfa); var terminal = new Terminal(regExp.ToString(), mClassIdProvider.GetCurrent()); return terminal; }
private void SetUpLexer() { // Ignore white space lexer.IgnoreTerminal(RegExp.AtLeastOneOf(RegExp.Choice(RegExp.Literal(' '), RegExp.Literal('\t')))); // Ignore comments (![a-zA-Z0-9...]\n) lexer.IgnoreTerminal(RegExp.Sequence(RegExp.Literal('!'), RegExp.AnyNumberOf(( RegExp.Range(' ', (char)255, encoding))))); // New line is delimiter between code lines mNewLine = lexer.UseTerminal(RegExp.Choice(RegExp.Literal('\n'), RegExp.Literal(0x0D), RegExp.Literal(0x0A))); mIdentifier = lexer.UseTerminal( RegExp.Sequence( RegExp.Choice(RegExp.Range('a', 'z', encoding), RegExp.Range('A', 'Z', encoding), RegExp.Literal('_')), RegExp.AnyNumberOf(RegExp.Choice(RegExp.Range('a', 'z', encoding), RegExp.Range('A', 'Z', encoding), RegExp.Literal('_'), RegExp.Range('0', '9', encoding))))); mRegister = lexer.UseTerminal(RegExp.Sequence(RegExp.Literal('r'), RegExp.Range('0', '9', encoding), RegExp.Optional(RegExp.Range('0', '9', encoding)))); mNumber = lexer.UseTerminal(RegExp.Sequence(RegExp.Optional(RegExp.Literal('-')), RegExp.AtLeastOneOf(RegExp.Range('0', '9', encoding)))); mHexNumber = lexer.UseTerminal(RegExp.Sequence(RegExp.Literal("0x"), RegExp.AtLeastOneOf(RegExp.Choice( RegExp.Range('0', '9', encoding), RegExp.Range('a', 'f', encoding))))); mComma = lexer.UseTerminal(RegExp.Literal(',')); mDot = lexer.UseTerminal(RegExp.Literal('.')); mSemicolon = lexer.UseTerminal(RegExp.Literal(';')); mColon = lexer.UseTerminal(RegExp.Literal(':')); mSlash = lexer.UseTerminal(RegExp.Literal('/')); mSquareBraceOpen = lexer.UseTerminal(RegExp.Literal('[')); mSquareBraceClose = lexer.UseTerminal(RegExp.Literal(']')); mPlus = lexer.UseTerminal(RegExp.Literal('+')); mDirective = lexer.UseTerminal(RegExp.Sequence(RegExp.Literal('.'), RegExp.Choice(RegExp.Literal("include"), RegExp.Literal("text"), RegExp.Literal("if"), RegExp.Literal("else"), RegExp.Literal("endif")), RegExp.AnyNumberOf( RegExp.Range(' ', (char)255, encoding)))); mDotC = lexer.UseTerminal(RegExp.Literal(".c")); }
private void SetUpLexer() { mIdentifier = lexer.UseTerminal(RegExp.Sequence( // ([a-z]+::)?[a-z]+ RegExp.Optional( // ([a-z]+::)? RegExp.Sequence( //[a-z]+:: RegExp.AtLeastOneOf(RegExp.Range('a', 'z', encoding)), RegExp.Literal("::")) ), RegExp.AtLeastOneOf(RegExp.Range('a', 'z', encoding)) )); mEqualSign = lexer.UseTerminal(RegExp.Literal('=')); // Ignore white space lexer.IgnoreTerminal(RegExp.AtLeastOneOf(RegExp.Choice(RegExp.Literal(' '), RegExp.Literal('\t'), RegExp.Literal('\n'), RegExp.Literal(0x0D), RegExp.Literal(0x0A)))); mPlusSign = lexer.UseTerminal(RegExp.Literal('+')); mMinusSign = lexer.UseTerminal(RegExp.Literal('-')); mAsterisk = lexer.UseTerminal(RegExp.Literal('*')); mDevideSign = lexer.UseTerminal(RegExp.Literal('/')); mNumber = lexer.UseTerminal(RegExp.Sequence(RegExp.Optional(RegExp.Literal('-')), RegExp.AtLeastOneOf(RegExp.Range('0', '9', encoding)))); mSemicolon = lexer.UseTerminal(RegExp.Literal(';')); mLeftBrace = lexer.UseTerminal(RegExp.Literal('(')); mRightBrace = lexer.UseTerminal(RegExp.Literal(')')); mComma = lexer.UseTerminal(RegExp.Literal(',')); }