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
- ImageMap.cs
- WebPartHeaderCloseVerb.cs
- ConstructorBuilder.cs
- NamespaceEmitter.cs
- FrameworkContextData.cs
- FactoryMaker.cs
- HighlightComponent.cs
- DataRelationCollection.cs
- BaseHashHelper.cs
- KeyValuePairs.cs
- StorageMappingItemCollection.cs
- XmlSchemaObject.cs
- SchemaSetCompiler.cs
- OperationInfo.cs
- InputProcessorProfiles.cs
- ToolStripTextBox.cs
- unitconverter.cs
- KeyPullup.cs
- CacheSection.cs
- SecurityTokenSerializer.cs
- MailMessageEventArgs.cs
- ScriptingRoleServiceSection.cs
- XmlSchemaObjectCollection.cs
- DesignerActionMethodItem.cs
- HashAlgorithm.cs
- SerializerWriterEventHandlers.cs
- SiteMapHierarchicalDataSourceView.cs
- ReadOnlyPropertyMetadata.cs
- SaveFileDialogDesigner.cs
- PartDesigner.cs
- WebControlAdapter.cs
- ProxyWebPartManager.cs
- AutomationElement.cs
- StringArrayConverter.cs
- FileDialogCustomPlacesCollection.cs
- DispatcherOperation.cs
- SQLConvert.cs
- TableAdapterManagerMethodGenerator.cs
- WebMessageBodyStyleHelper.cs
- Span.cs
- ConnectionConsumerAttribute.cs
- WindowsIPAddress.cs
- XmlSchemaRedefine.cs
- FormsAuthenticationEventArgs.cs
- WebControl.cs
- WaitHandle.cs
- TypeSystem.cs
- TypeDefinition.cs
- input.cs
- MultilineStringConverter.cs
- DynamicDiscoSearcher.cs
- DataGridPageChangedEventArgs.cs
- TimeSpanFormat.cs
- ScriptIgnoreAttribute.cs
- WindowsScrollBar.cs
- DesignOnlyAttribute.cs
- Dynamic.cs
- SoapSchemaExporter.cs
- WebServiceTypeData.cs
- ResourceDisplayNameAttribute.cs
- WebColorConverter.cs
- DbProviderServices.cs
- Point3DCollection.cs
- ServiceDesigner.cs
- ImageEditor.cs
- SettingsBindableAttribute.cs
- DataGridViewSortCompareEventArgs.cs
- ScrollItemProviderWrapper.cs
- TraceSection.cs
- SafeFileMappingHandle.cs
- SynchronizedDisposablePool.cs
- OdbcUtils.cs
- XamlPointCollectionSerializer.cs
- SourceChangedEventArgs.cs
- URL.cs
- LowerCaseStringConverter.cs
- ImageAttributes.cs
- XPathSingletonIterator.cs
- ImageSource.cs
- StringHelper.cs
- InstanceHandle.cs
- FunctionDescription.cs
- TextProviderWrapper.cs
- RawStylusInputCustomDataList.cs
- SoapServerMethod.cs
- EntityDesignerDataSourceView.cs
- HostSecurityManager.cs
- ConnectionProviderAttribute.cs
- RectAnimation.cs
- TransformCollection.cs
- BufferedGraphics.cs
- EventLog.cs
- BuildTopDownAttribute.cs
- DCSafeHandle.cs
- Help.cs
- DataServiceProcessingPipeline.cs
- IODescriptionAttribute.cs
- ReceiveParametersContent.cs
- XamlUtilities.cs
- PassportIdentity.cs