/// <summary> /// Initializes a new instance of the Variable class. /// </summary> /// <param name="type"> /// The type of the variable. /// </param> /// <param name="name"> /// The name of the variable. /// </param> /// <param name="modifiers"> /// Modifiers applied to this variable. /// </param> /// <param name="location"> /// The location of the variable. /// </param> /// <param name="parent"> /// The parent code part. /// </param> /// <param name="generated"> /// Indicates whether the variable is located within a block of generated code. /// </param> internal Variable(TypeToken type, string name, VariableModifiers modifiers, CodeLocation location, Reference <ICodePart> parent, bool generated) { Param.Ignore(type); Param.AssertValidString(name, "name"); Param.Ignore(modifiers); Param.AssertNotNull(location, "location"); Param.AssertNotNull(parent, "parent"); Param.Ignore(generated); this.type = type; this.name = CodeLexer.DecodeEscapedText(name, true); this.modifiers = modifiers; this.location = location; this.parent = parent; this.generated = generated; }
/// <summary> /// Creates a text string based on the child tokens in the attribute. /// </summary> private void CreateTextString() { StringBuilder tokenText = new StringBuilder(); foreach (CsToken token in this.Tokens) { // Strip out comments and preprocessor directives. if (token.CsTokenType != CsTokenType.SingleLineComment && token.CsTokenType != CsTokenType.MultiLineComment && token.CsTokenType != CsTokenType.PreprocessorDirective) { string decodedText = CodeLexer.DecodeEscapedText(token.Text, true); tokenText.Append(decodedText); } } this.text = tokenText.ToString(); }
static void Main(string[] args) { #if debugenabled try { #endif string Code = File.ReadAllText("Tests\\Ackermann.cs"); CodeLexer lexer = new CodeLexer(Code); LexTokenList lexTokens = lexer.Analyze(); CPreprocessor preProcessor = new CPreprocessor(lexTokens); lexTokens = preProcessor.Process(); Console.WriteLine("LexTokens (post-processed):"); foreach (LexToken lexToken in lexTokens) { Console.WriteLine(lexToken.Kind.ToString() + " " + (lexToken.Value == null ? "" : lexToken.Value.ToString())); } Console.WriteLine("------\nGenerating AST.."); AstGenerator astGenerator = new AstGenerator(lexTokens); StatementList statements = astGenerator.Generate(); Console.WriteLine("Generated AST!"); Console.WriteLine(View.ASTView.GenerateStatements(statements)); #if debugenabled } catch (Exception ex) { Console.WriteLine(ex.Message + "\n" + ex.StackTrace); } #endif Console.ReadLine(); }
/// <summary>Reads a JSON array from the given parser.</summary> private static JSObject ReadObject(CodeLexer parser) { // Kick it off: char current = parser.Peek(); // The read key: string key = ""; // And one for the value: StringBuilder value = new StringBuilder(); bool valueString = false; bool inString = false; char stringChar = '\0'; // Is the current letter in "escaped" mode? bool escaped = false; JSObject result = null; while (current != StringReader.NULL) { if (inString) { if (escaped) { value.Append(current); escaped = false; } else if (current == stringChar) { // Exiting the string: parser.Literal = false; inString = false; } else if (current == '\\') { // Escape: escaped = true; } else { value.Append(current); } } else if (current == '"' || current == '\'') { // Track which it was: stringChar = current; // Entering the string: parser.Literal = true; inString = true; valueString = true; } else if (current == '{' || current == '[') { if (result != null) { // Reading an object: JSObject arr = ReadObject(parser); if (key != "") { result[key] = arr; } else { result.push(arr); } // Use up the key: key = ""; } else { result = new JSArray(); } } else if (current == '}' || current == ']' || current == ',') { // Complete the value if we need to. string val = value.ToString(); value.Length = 0; if (!valueString && val == "null") { val = null; } valueString = false; if (key != "") { result[key] = new JSValue(val); key = ""; } else if (val != "") { result.push(val); } if (current != ',') { break; } } else if (current == ':') { // We just read a key: key = value.ToString(); value.Length = 0; valueString = false; } else { // Add to value: value.Append(current); } // Read it off: parser.Read(); // Peek next one: current = parser.Peek(); } if (value.Length != 0) { if (result == null) { // Get the value string: string val = value.ToString(); if (!valueString && val == "null") { // It was the word "null". return(null); } result = new JSValue(val); } else { // Malformed - missing closing bracket. throw new Exception("JSON syntax error: Closing bracket missing."); } } return(result); }
/// <summary> /// Initializes a new instance of the CsElement class. /// </summary> /// <param name="document"> /// The document that contains the element. /// </param> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="type"> /// The element type. /// </param> /// <param name="name"> /// The name of this element. /// </param> /// <param name="header"> /// The Xml header for this element. /// </param> /// <param name="attributes"> /// The list of attributes attached to this element. /// </param> /// <param name="declaration"> /// The declaration code for this element. /// </param> /// <param name="unsafeCode"> /// Indicates whether the element is unsafe. /// </param> /// <param name="generated"> /// Indicates whether the element was generated or written by hand. /// </param> internal CsElement( CsDocument document, CsElement parent, ElementType type, string name, XmlHeader header, ICollection <Attribute> attributes, Declaration declaration, bool unsafeCode, bool generated) : base(CodePartType.Element) { Param.AssertNotNull(document, "document"); Param.Ignore(parent); Param.Ignore(type); Param.AssertNotNull(name, "name"); Param.Ignore(header); Param.Ignore(attributes); Param.Ignore(declaration); Param.Ignore(unsafeCode); Param.Ignore(generated); this.document = document; if (this.document == null) { throw new ArgumentException(Strings.DocumentMustBeCsDocument, "document"); } if (parent != null && parent.Document != document) { throw new ArgumentException(Strings.ElementMustBeInParentsDocument, "parent"); } this.type = type; this.name = CodeLexer.DecodeEscapedText(name, true); this.header = header; this.attributes = attributes; this.declaration = declaration; this.unsafeCode = unsafeCode; this.generated = generated; if (!unsafeCode && this.declaration.ContainsModifier(CsTokenType.Unsafe)) { this.unsafeCode = true; } // Fill in the element reference in the header object. if (this.header != null) { Debug.Assert(this.header.Element == null, "The header element should not be empty."); this.header.Element = this; } // Fill in the element reference in the attributes list items. if (this.attributes != null) { Debug.Assert(this.attributes.IsReadOnly, "The attributes collection should be read-only."); foreach (Attribute attribute in this.attributes) { Debug.Assert(attribute.Element == null, "The attribute element should not be empty"); attribute.Element = this; } } // Set the fully qualified base name if (parent != null) { this.fullyQualifiedBase = parent.FullyQualifiedName; this.MergeAccess(parent.ActualAccess); } else { if (this.declaration != null) { this.actualAccess = this.declaration.AccessModifierType; } else { this.actualAccess = AccessModifierType.Public; } } // Set the fully qualified name this.fullyQualifiedName = this.fullyQualifiedBase; if (this.declaration != null && this.declaration.Name != null && this.declaration.Name.Length > 0) { if (this.fullyQualifiedBase != null && this.fullyQualifiedBase.Length > 0) { this.fullyQualifiedName += "."; } int index = this.declaration.Name.LastIndexOf("\\", StringComparison.Ordinal); if (index != -1) { this.fullyQualifiedName += this.declaration.Name.Substring(index + 1, this.declaration.Name.Length - index - 1); } else { this.fullyQualifiedName += this.declaration.Name; } index = this.fullyQualifiedName.IndexOf(".cs.", StringComparison.OrdinalIgnoreCase); if (-1 == index) { this.fullNamespaceName = this.fullyQualifiedName; } else { this.fullNamespaceName = this.fullyQualifiedName.Substring(index + 4, this.fullyQualifiedName.Length - index - 4); } } // There is only one type of element which is allowed to have a token // list consisting of nothing other than whitespace, newlines, etc., // which is the document root. This happens if you have a document which // contains nothing other than whitespace. Due to this we do not want to // trim down the token list for the root element, but we do want to for // all other types of elements. if (type == ElementType.Root) { this.TrimTokens = false; } }
/// <summary> /// Extracts the body of the given preprocessor directive symbol, parses it, and returns the parsed expression. /// </summary> /// <param name="document">The parent document.</param> /// <param name="code">The source code.</param> /// <param name="parentProxy">Represents the parent item.</param> /// <param name="languageService">The C# language service.</param> /// <param name="preprocessorDefinitions">Optional preprocessor definitions.</param> /// <param name="preprocessorSymbol">The preprocessor directive symbol.</param> /// <param name="startIndex">The index of the start of the expression body within the text string.</param> /// <returns>Returns the expression.</returns> internal static Expression GetConditionalPreprocessorBodyExpression( CsDocument document, Code code, CodeUnitProxy parentProxy, CsLanguageService languageService, IDictionary <string, object> preprocessorDefinitions, Symbol preprocessorSymbol, int startIndex) { Param.AssertNotNull(document, "document"); Param.AssertNotNull(code, "code"); Param.AssertNotNull(parentProxy, "parentProxy"); Param.AssertNotNull(languageService, "languageService"); Param.Ignore(preprocessorDefinitions); Param.AssertNotNull(preprocessorSymbol, "preprocessorSymbol"); Param.AssertGreaterThanOrEqualToZero(startIndex, "startIndex"); CsLanguageService.Debug.Assert(preprocessorSymbol.SymbolType == SymbolType.PreprocessorDirective, "The symbol is not a preprocessor directive."); string text = preprocessorSymbol.Text.Substring(startIndex, preprocessorSymbol.Text.Length - startIndex).TrimEnd(null); if (text.Length > 0) { // Trim off the whitespace at the beginning and advance the start index. int trimIndex = 0; for (int i = 0; i < text.Length; ++i) { if (char.IsWhiteSpace(text[i])) { ++trimIndex; } else { break; } } if (trimIndex > 0) { text = text.Substring(trimIndex, text.Length - trimIndex); startIndex += trimIndex; } if (text.Length > 0) { // Extract the symbols within this text. Code preprocessorCode = new Code(text, "Preprocessor", "Preprocessor"); var lexer = new CodeLexer( languageService, preprocessorCode, new CodeReader(preprocessorCode), preprocessorSymbol.Location.StartPoint.Index + startIndex, preprocessorSymbol.Location.StartPoint.IndexOnLine + startIndex, preprocessorSymbol.Location.StartPoint.LineNumber); List <Symbol> symbolList = lexer.GetSymbols(document, null); var directiveSymbols = new SymbolManager(symbolList); var preprocessorBodyParser = new CodeParser(languageService, document, directiveSymbols, preprocessorDefinitions); // Parse these symbols to create the body expression. return(preprocessorBodyParser.GetNextConditionalPreprocessorExpression(document, parentProxy)); } } // The directive has no body. return(null); }
/// <summary> /// Gets the contents of the expression as a string. /// </summary> /// <returns>Returns the string.</returns> public override string ToString() { return(CodeLexer.DecodeEscapedText(this.tokenNode.Value.Text, false)); }