Tweets by @Actipro
Please take some time to learn more about us and our product offerings.
As mentioned in a previous post we have been working very hard on developing a custom grammar and AST object model that will be an optional free part of SyntaxEditor for WPF/Silverlight products going forward, hopefully starting with the 2010.2 version.
We’ve been using this new grammar/AST design to prototype out a WPF version of an advanced XML syntax language implementation. The XML language will eventually contain the same or better feature set as those found in the WinForms Web Languages Add-on.
Today I’d like to give a quick glimpse into some initial features we have working.
Our new grammar has a tree construction syntax that makes it very easy to create an AST of a document. Take this XML code for example…
The grammar parser we built for XML will construct an AST that looks like this when output to a string:
CompilationUnit[ Element[ "a" Nodes[ Element[ "b" Nodes[ Comment ] EndTag ] ] EndTag ] ]
CompilationUnit[ Element[ "a" Nodes[ Element[ "b" Nodes[ Comment ] EndTag ] ] EndTag ] ]
Each node in the AST automatically gets assigned an offset range based on what generated it, which becomes important when we get into features below such as code outlining. More...
We found that the free SyntaxEditor .langproj (language project) files we offer for over 20 sample languages weren’t included in our Silverlight Studio install like they were in the WPF Studio install. We’ve redeployed last week’s build 101 so that it now includes the missing .langproj files. You can now open and use them as you please in our Language Designer. No product code changes were made in this redeploy.
We’ve just released Silverlight Studio 2010.1 build 101. We’ve got some great new features in this build.
As described in this previous post, the ToolBar control in our Shared Library has been updated to support overflow of controls to a popup and vertical orientation.
The screenshot above shows both features in action.
SyntaxEditor for WPF has a great control called EditorSearchView that you can drop into a window and instantly provide find/replace functionality to you end users.
With today’s release, now SyntaxEditor for Silverlight has it too. You can quickly toggle between find and replace modes using our ToolBar control and all of the standard find/replace options are available to the end user.
Finally, we’ve added a default context menu to SyntaxEditor for Silverlight to make it even more user-friendly.
The context menu has the standard editing options available.
The new build is live right now. Check out the announcement post for change details. Enjoy!
We get asked all the time when our popular .NET Languages Add-on and Web Languages Add-on for the WinForms SyntaxEditor will be ported over to WPF and Silverlight. The missing feature area that we need before we can do that is our own grammar/AST framework.
The WPF and Silverlight SyntaxEditor controls already have an IParser interface in place along with the ability to automatically call a language’s registered parser in a worker thread after any text change. Since we use interfaces for our design, any first- or third-party parser can be easily used with our framework. The IParser’s purpose is to parse through document text and produce some parse data results, which could be an AST (abstract syntax tree), syntax error list, etc.
A grammar framework is the ability to define a parser, generally via some form of EBNF. In some grammar implementations the parser is code-generated and in other implementations a parser is more like a regex engine and interprets input based on dynamic grammar data.
The most common output from a parser is an AST, which is a hierarchy of syntax tree nodes that describe the contents of the document.
We could make our language add-ons rely on third-party parser products like ANTLR (we already have a free add-on that enables integration with ANTLR parsers), however many of our customers require that code they purchase from us is not reliant on third-party functionality. Also when we have our own custom grammar/AST framework, we can add more customized editor-related functionality than what is possible with a third-party parser framework.
The WinForms SyntaxEditor’s grammar/AST model is what is used by the language add-ons there. It is a recursive descent parser with infinite look-ahead capabilities. While it works great and has many features, there are several drawbacks that we are looking to improve upon with our newer design that will be prototyped out in the WPF/Silverlight SyntaxEditors:
We’ve had a good look at a lot of grammars and parser generators over the years and we’ve been considering ideas on how to improve our own grammar/AST framework moving forward. We’ve already started prototyping out a number of ideas to see if they pan out well.
Our plan is to stick with a recursive descent parser with infinite look-ahead capabilities like in WinForms. Here’s some preliminary ideas of how we’re trying to improve upon the WinForms’ grammar/AST framework and address each of the drawbacks above.
One thing we want to achieve if possible is allowing you to write your grammar using EBNF-like notation but in your actual language you write code in. We can actually achieve a pretty nice, compact syntax that is EBNF-like and uses language features like implicit type casting, operator overloading, etc. Some of this is already working in our prototype.
Here’s a grammar snippet written in C# that parses an XML start tag:
1: startTag.Production = tStartTagStartDelimiter + tStartTagName["tagName"] +
3: tStartTagAttribute["attrName"] +
4: tStartTagAttributeStringValueStartDelimiter +
5: tStartTagAttributeStringValueText.Optional() +
7: > AstFrom("attrName")
8: ).ZeroOrMore().SetLabel("attrs") +
10: > Ast("StartTag", AstFrom("tagName"), Ast("Attributes", AstValuesFrom("attrs")));
Any variable that has a t at the start of its name is a Terminal, and will match a token. Terminal and NonTerminal objects used in the grammar have already been defined in code above this snippet. Terminals and NonTerminals implicitly type convert to EbnfTerm-based objects when used in a production rule like above. Any EbnfTerm has methods on it such as ZeroOrMore, OneOrMore, and Optional that let you implement Kleene operators. The + operator is used for concatination of EbnfTerms and the | operator is used to achieve alternation. Thus we have achieved EBNF-like syntax but in C# and VB.
In this prototype design, we’ve kept AST nodes truly generic. Basically they have a Key value and a list of child nodes, that’s it. There will likely end up being a couple more properties on them (such as text range) but our goal is to keep the AST nodes as simple as possible.
We have some ideas to allow concrete classes to be built that will “wrap” the generic AST nodes and provide a more consumable object model that is specific to a language.
You’ll notice at the end of the code snippet above we have this:
1: > Ast("StartTag", AstFrom("tagName"), Ast("Attributes", AstValuesFrom("attrs")));
That portion of the production rule is saying how to perform AST node construction. If you don’t specify a construction rule then an AST node hierarchy will automatically be built for you based on what is matched in the non-terminal. However in most cases, the default hierarchy that is created contains more information than what you really need or care about. Therefore most productions should have customized tree construction rules associated with them.
In this snippet’s scenario, we are saying we want this start tag non-terminal to build an AST node with value StartTag and whose first child node comes from the match made by the EbnfTerm that was given a label tagName. Since in the production rule a Terminal was used to match the tag name, the terminal’s value (the actual tag name) will be the value of the AST node that is created under the StartTag node. Next we say that we wish to have an Attributes AST node as the second child and its children will be all the results pulled from the EbnfTerm that was labeled attrs.
Given this input:
1: <Block Attr="Value" Attr2="Value2">
We get this string representation of AST node output:
This sort of AST node construction makes it super easy to create meaningful output from your parser in a minimal amount of time.
You may be thinking: Hey this works great with one token look-ahead. But what about more complex scenarios where we need to peek ahead multiple tokens to determine how to process something?
What we’ve done is added code injection points that can be inserted on any EbnfTerm. For instance you can inject a delegate that executes when any EbnfTerm is about to be matched, or when it succeeds or fails. Since they are delegates, you can write them inline if you wish and can even reuse them multiple places in the grammar.
You can use code injection to tweak the AST node output too.
As you can see we have a lot of ideas for the prototype we’re building. We want to hear your ideas too. What do you like and not like about these ideas? Do you have suggestions for other features you’d like to see?
Please post or email your comments to us. Now is the time to get them in, while we’re still in a design phase.
Our Silverlight Studio bundle contains a custom ToolBar control in the Shared Library, along with Menu and ContextMenu controls.
Here is how it looks in the default Aero theme, although the current official release doesn’t yet have the overflow button at the end. That is a new feature that has been added for the next maintenance release. Basically the overflow button is disabled unless there isn’t enough space to display all of the child controls.
In that case the overflow button can be clicked to display a popup that contains all of the child controls that weren’t able to fit on the main toolbar. The Office black-themed screenshot above shows the overflow popup.
In addition, we’ve added vertical orientation capabilities as seen in the Office blue-themed screenshot above. By setting the new Orientation property to Vertical, the toolbar renders vertically and even auto-rotates the background/border brushes and padding for you.
These new features will be in the next maintenance release of Silverlight Studio.
Yesterday we posted information on performance enhancements that have been made to PropertyGrid for WPF that will appear in the future WPF Studio 2010.2 version. Today I’d like to show a new feature that has also been added for that version.
Nested categories, meaning categories within categories, are available when setting the new PropertyGrid.AreNestedCategoriesSupported property to true and can be used with either the SelectedObject(s) or Properties properties.
Nested categories are created by specifying the “path” to the desired category, versus the actual name. For example, using a category name of One\Two would create a root category titled One, which contains a nested category titled Two.
The screenshot above shows numerous nested categories within the PropertyGrid.
Any level of nested categories can be created, with each name separate by a backslash (\). If a backslash is required in any of the categories, that part can be wrapped in single or double quotes. For example, One\’Two\2’ would create a root category titled One, which contains a nested category titled Two\2.
All properties and categories will be combined, based on their “path”. For example, if two properties both define a category of One\Two, then both properties will be located in the category titled Two. If one property defines a category of One\Two and another property defines a category of One, then the category titled One will contain the category titled Two and the latter property (and the former property will be contained in the category titled Two).
As mentioned above, these updates will be in the future WPF Studio 2010.2 version.
We’ve been hard at work on enhancements for our WPF controls that will be part of our WPF Studio 2010.2 version. One of the areas we’ve gotten into is reworking a lot of the internals of our PropertyGrid control to improve performance.
PropertyGrid was already performing comparable to other WPF property grids, however we have taken a long look at several areas that we identified could provide some additional performance gains, and have updated our code to take advantage of the ideas.
Without getting into too much detail, we have focused on changes that would reduce the overall number of visuals and measure/arrange cycles that were required.
We also have added some options that further improve performance when set appropriately:
All of these features are complete for the WPF Studio 2010.2 version that should be released in the next couple months.
We’ve just sent out our July 2010 newsletter to subscribers and have posted it online as well in case you are not a subscriber.
You can view the newsletter online via this link:
We list our development plan for the next several months at the end of the newsletter in its What’s next? section.
In Quarter 2 of 2010 we had several major product releases.
WPF Studio 2010.1 was launched, which added the new Views for WPF product, made numerous enhancements to various WPF control products, updated all products to target .NET 3.5 SP1, and added Visual Studio 2010 integration.
Silverlight Studio, our new bundle of controls for the Silverlight 4 platform, was also launched. It contains ports of our popular SyntaxEditor code editor control and the new Views for WPF product, along with other useful controls and components found in its Shared Library.
Finally, we relaunched WPFpedia.com, our 100% free community resource guide for WPF developers. It is written using the latest web technologies and allows you to easily find information on nearly any WPF development-related topic on the web.
Now that we are past the Silverlight Studio release, we’re jumping back on adding new features and enhancements to our existing WPF products for a while. We have a lot of updates planned over the coming weeks so stay tuned to our blog for details.
For a high-level list of what we’ll be working on, please see the July 2010 newsletter that will be posted shortly.
Here is a quick categorized list of useful blog postings made in this quarter. More...