Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Activities / Rules / Parser / Intellisense.cs / 1305376 / Intellisense.cs
using System; using System.Collections.Generic; using System.Collections; using System.Workflow.Activities.Rules; namespace System.Workflow.Activities.Rules { internal class IntellisenseParser { private Listtokens = new List (); private int tokenIndex; internal IntellisenseParser(string inputString) { Scanner scanner = new Scanner(inputString); // Tokenize the input, but insert a marker at the beginning. tokens.Add(new Token(TokenID.EndOfInput, 0, null)); scanner.TokenizeForIntellisense(tokens); } private Token CurrentToken { get { return tokens[tokenIndex]; } } private Token PrevToken() { if (tokenIndex > 0) --tokenIndex; return CurrentToken; } internal ParserContext BackParse() { tokenIndex = tokens.Count - 1; if (tokenIndex < 0) return null; Token token = CurrentToken; bool valid = false; // Skip past the right-most EndOfIput. For our backparsing, we've inserted an // EndOfInput at the start. if (token.TokenID == TokenID.EndOfInput) token = PrevToken(); int endTokenIndex = tokenIndex; if (token.TokenID == TokenID.Identifier && ((string)token.Value).Length == 1 && PrevToken().TokenID != TokenID.Dot) { // Assume this is the start of a root identifier valid = true; } else if (token.TokenID == TokenID.Dot) { // Assume it's a member selection operator. valid = BackParsePostfix(); } else if (token.TokenID == TokenID.LParen) { // Assume it's the start of a method call argument list. if (PrevToken().TokenID == TokenID.Identifier) { if (PrevToken().TokenID == TokenID.Dot) { // The tail looked like ".identifier(", so now we continue as in // the member selection operator reverse parse above. valid = BackParsePostfix(); } else { // The tail looked like "identifier(", with no preceeding ".", so // we're actually done. valid = true; } if (valid) { // Back up over the "new" if there is one. if (CurrentToken.TokenID == TokenID.New) PrevToken(); } } } if (!valid) return null; // We successfully backward-parsed a postfix expression. Create a // ParserContext for the real parser, giving it the subrange of tokens // that comprise the postfix expression. List postfixTokens = tokens.GetRange(tokenIndex + 1, endTokenIndex - tokenIndex); postfixTokens.Add(new Token(TokenID.EndOfInput, 0, null)); ParserContext parserContext = new ParserContext(postfixTokens); return parserContext; } private bool BackParsePostfix() { while (CurrentToken.TokenID == TokenID.Dot) { Token token = PrevToken(); switch (token.TokenID) { case TokenID.Identifier: case TokenID.TypeName: PrevToken(); // eat the token break; case TokenID.This: PrevToken(); // eat the "this" // This is the start of the expression. return true; case TokenID.RParen: // This may be the argument list of a method call, // or it may be a parenthesized expression. if (!BackParseMatchingDelimiter(TokenID.LParen)) return false; if (CurrentToken.TokenID == TokenID.Identifier) { // It was a method call. PrevToken(); // eat the method identifier } else { // It was a parenthesized subexpression. We are finished, // we have found the start of the subexpression. return true; } break; case TokenID.RBracket: // Loop backward over all [..][..] do { if (!BackParseMatchingDelimiter(TokenID.LBracket)) return false; } while (CurrentToken.TokenID == TokenID.RBracket); // Preceeding the indexers might be an identifier, or a method call. if (CurrentToken.TokenID == TokenID.Identifier) { // It was an identifier. Eat it and continue. PrevToken(); // eat the identifier. } else if (CurrentToken.TokenID == TokenID.RParen) { // This may be the argument list of a method call, // or it may be a parenthesized expression. if (!BackParseMatchingDelimiter(TokenID.LParen)) return false; if (CurrentToken.TokenID == TokenID.Identifier) { // It was a method call. PrevToken(); // eat the method identifier } else { // It was a parenthesized subexpression. We are finished, // we have found the start of the subexpression. return true; } } else { // It's not valid. return false; } break; case TokenID.Greater: if (!BackParseMatchingDelimiter(TokenID.Less)) return false; if (CurrentToken.TokenID == TokenID.Identifier) { // It was a generic type PrevToken(); // Eat the type identifier } else { // This wasn't valid... it was a type argument list, but wasn't // preceeded by an identifier. return false; } break; default: // We saw a "." that wasn't preceeded by a useful token. return false; } } // If an identifier or type name is preceeded by "new", keep that. if (CurrentToken.TokenID == TokenID.New) PrevToken(); return true; } // Having parsed a closing delimiter, eat tokens until the matching open delimiter // is found. private bool BackParseMatchingDelimiter(TokenID openDelimiter) { TokenID closeDelimiter = CurrentToken.TokenID; int level = 1; Token token = PrevToken(); // Eat the close delimiter while (token.TokenID != TokenID.EndOfInput) { if (token.TokenID == closeDelimiter) { ++level; } else if (token.TokenID == openDelimiter) { --level; if (level == 0) { PrevToken(); // eat the open delimiter break; } } token = PrevToken(); } // Back parse was successful if we matched all delimiters. return level == 0; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- MaterialCollection.cs
- JsonFormatMapping.cs
- SmtpTransport.cs
- DataControlButton.cs
- FilterQueryOptionExpression.cs
- FormatSettings.cs
- CompilationRelaxations.cs
- DataGridViewTextBoxCell.cs
- ETagAttribute.cs
- Walker.cs
- NopReturnReader.cs
- ActivityCodeDomSerializer.cs
- DesigntimeLicenseContextSerializer.cs
- Internal.cs
- Soap12FormatExtensions.cs
- HwndSource.cs
- CorrelationTokenTypeConvertor.cs
- StylusPointDescription.cs
- DrawingState.cs
- QilInvokeLateBound.cs
- PassportAuthenticationModule.cs
- RoutedEventArgs.cs
- MouseBinding.cs
- Color.cs
- CodeMemberEvent.cs
- SynchronizedInputPattern.cs
- PersistenceProviderDirectory.cs
- RequestCacheValidator.cs
- ReceiveSecurityHeaderElementManager.cs
- Environment.cs
- AssociationEndMember.cs
- RichTextBoxAutomationPeer.cs
- IntSecurity.cs
- WebPartZone.cs
- Assert.cs
- UIPermission.cs
- DeleteBookmarkScope.cs
- StringOutput.cs
- LinqDataSourceEditData.cs
- WebControlsSection.cs
- RelationshipType.cs
- RequestContext.cs
- RepeatBehavior.cs
- RadioButtonPopupAdapter.cs
- DataPagerFieldCommandEventArgs.cs
- HyperLinkStyle.cs
- RuleRefElement.cs
- StreamGeometryContext.cs
- SelectedDatesCollection.cs
- XmlRawWriterWrapper.cs
- BaseTreeIterator.cs
- ItemContainerGenerator.cs
- MatrixIndependentAnimationStorage.cs
- EmptyElement.cs
- Menu.cs
- DataGridViewCellErrorTextNeededEventArgs.cs
- Block.cs
- DocumentPageTextView.cs
- PropertySegmentSerializer.cs
- SettingsBindableAttribute.cs
- ConstraintEnumerator.cs
- TypeRefElement.cs
- ObjectViewEntityCollectionData.cs
- LogExtentCollection.cs
- MemoryPressure.cs
- PersonalizableTypeEntry.cs
- XmlEntity.cs
- RIPEMD160Managed.cs
- SqlNotificationEventArgs.cs
- GeometryGroup.cs
- NullableDecimalMinMaxAggregationOperator.cs
- IncrementalReadDecoders.cs
- CacheDependency.cs
- AffineTransform3D.cs
- NavigationPropertyEmitter.cs
- ListViewGroup.cs
- DelegatingTypeDescriptionProvider.cs
- XmlAnyElementAttributes.cs
- PixelFormat.cs
- WebConfigurationManager.cs
- NominalTypeEliminator.cs
- CollectionView.cs
- EraserBehavior.cs
- HttpListenerTimeoutManager.cs
- ConnectionStringSettings.cs
- SuppressIldasmAttribute.cs
- CompilerWrapper.cs
- CDSCollectionETWBCLProvider.cs
- SamlConditions.cs
- IgnoreFileBuildProvider.cs
- CriticalFinalizerObject.cs
- ActiveXContainer.cs
- WindowsScrollBar.cs
- QualifierSet.cs
- HTTP_SERVICE_CONFIG_URLACL_KEY.cs
- DictionaryBase.cs
- FrameworkElementAutomationPeer.cs
- ApplicationManager.cs
- HtmlTableCellCollection.cs
- WCFServiceClientProxyGenerator.cs