Subscribe (RSS)

Quick Links

About Actipro

Actipro Software has been creating .NET user interface control products for Windows Forms since its inception. More recently, Actipro has become a pioneer in the .NET 3.0 WPF control development arena.

SyntaxEditor for WPF to get squiggle tag quick info provider

by Bill Henning (Actipro) September 2, 2010 at 03:29

The 2010.2 version of SyntaxEditor for WPF (and the same for the 2010.2 Silverlight Studio release) will get a new built-in language service called SquiggleTagQuickInfoProvider that you can register on your language.  When this service is registered and the mouse is moved over a squiggle, it checks the squiggle data to see if there is related content available that can be displayed in an IntelliPrompt popup.  If so, it displays it.  Here’s and example of quick info for a parse error:

SquiggleTagQuickInfoProvider

In this sample, we’re using the Web Languages Add-on’s XML language.  The XML parser returned that there was a parse error because there is an unexpected duplicate end tag.  We already have a built-in tagger that automatically looks for parse errors from a parser and makes squiggle lines in the editor for them.  Now with this new quick info provider, mouse hovers over the squiggles will also show the text of the parse error.

If you have a parser on your language that is capable of returning parse errors, then it just takes two lines of code to register the parse error tagger (which renders the squiggles) and the new squiggle tag quick info provider, thereby giving you all this functionality.

SyntaxEditor advanced XML language to get xs:any support for IntelliPrompt

by Bill Henning (Actipro) August 31, 2010 at 06:14

As mentioned in one of our previous posts, we’ve been working on a port of our SyntaxEditor Web Languages Add-on from WinForms to the WPF version of SyntaxEditor.  We’re finishing up some last features on it before it will be ready to launch alongside WPF Studio 2010.2 in the coming weeks.

The advanced XML syntax language implementation in the add-on allows you to specify XML schemas to use for validation and to drive automated IntelliPrompt for the end user.  In the previous post on the subject we showed how to create an XHTML editor in a few lines of code with automated IntelliPrompt popups.

One feature we just implemented was the ability to properly support xs:any nodes defined in the XML schemas.  xs:any allows a schema to indicate that elements from any, other, or specific namespaces can be included as content within another element.

Best of all, we ported this new functionality back to the WinForms Web Languages Add-on too!

Let’s see an example…

XsltWpf1

Here is the WPF SyntaxEditor showing an XSLT document loaded.  The XSLT is doing a transform to HTML.  In the screenshot the mouse is over the xsl:value-of element, showing a quick info tip.  Now let’s start typing a new start tag…  More...

SyntaxEditor for WPF - HTML editor sample preview using Web Languages Add-on

by Bill Henning (Actipro) August 26, 2010 at 09:20

We’ve been hard at work on WPF Studio 2010.2, which we should have out in September.  One new product that will ship along side of it is a port of our Web Languages Add-on that we have for the WinForms SyntaxEditor.

This add-on has an advanced XML syntax language implementation that allows you to specify an XML schema set to provide validation and automated IntelliPrompt within the code editor, all with just a few lines of code.  Let’s take a peek at a new HTML Editor demo we’re adding to WPF Studio to show off the add-on:

HtmlEditor1

Here we have the sample that shows an XHTML document loaded.  We’ve configured our advanced XML language with an XSD we downloaded from the W3C for XHTML.  And with a few lines of code, voila, instant HTML editor!  More...

SyntaxEditor grammar/AST framework part 8: Grammar debugger preview

by Bill Henning (Actipro) August 20, 2010 at 08:32

In the previous post, we added error handling to our Simple language grammar.  This allowed the grammar parser to recover from any invalid syntax in a document being parsed, and to still produce an AST.

It concluded the three basic stages in building a grammar:

  1. Configure terminals, non-terminals, and EBNF productions
  2. Add customized tree constructors to productions that create a concise AST
  3. Add error handling to recover from invalid syntax

Now what happens when in the middle of the grammar design and something is not parsing as intended?  It can be tricky to know what the parser is “thinking” since it’s a bit of a black box.

Debugger1

To solve this issue, we’ve built complete debugging capabilities directly into the parser and have even enhanced the Language Designer application to have a complete debugger UI!  More...

SyntaxEditor grammar/AST framework part 7: Adding error handling to the Simple grammar

by Bill Henning (Actipro) August 13, 2010 at 01:30

In the previous post, we saw how the grammar framework supports callbacks nearly everywhere in the EBNF terms.  You are able to inject custom code before and after any term is matched.  One of the most important injection points is the Error callback since that allows you to tell the parser how to handle errors.

In today’s post, we’ll examine the importance of adding error handling.  We’ll enhance our Simple language grammar to properly recover from nearly any invalid syntax in a document so that it can continue parsing the rest of the document.

Why add error handling?

An error occurs when one or more terminals is expected by the parser (per the grammar) but a different token is found at the current location in the document.

By default when this scenario occurs, the parser will report a parse error if a single terminal is expected.  If there is more than one terminal that could be next, and if the containing non-terminal has an error alias set, it will report a parse error instead.  This behavior is described in the previous post. 

Following any possible error reporting, the parser will immediately exit the current non-terminal and will continue up the non-terminal stack, exiting each one as it goes until the root non-terminal is reached and exited itself.

Thus the result is that if any invalid syntax is found in a document, parsing stops at that point and no AST will be built.  That’s definitely not good since we expect code being parsed from our SyntaxEditor control editing to be invalid most of the time.  End users are continuously typing in it.

As shown in the previous post, the grammar framework has a lot ways to recover from errors, and they are easy to add.  More...

SyntaxEditor grammar/AST framework part 6: Introduction to callbacks and error handling

by Bill Henning (Actipro) August 12, 2010 at 01:22

In the previous post, we optimized the tree construction output of our Simple language to be very concise.  The next step in building a grammar is to make sure that it properly handles errors.  After all, since this grammar framework is intended to be used with SyntaxEditor, our code editor control, we have to assume that most of the time the document’s code passed to our grammar parser will be in an invalid state.  The user is continuously typing and modifying it.

In today’s post we will look at the various callbacks that are available to you, probably the most important of which are error handling callbacks.  We’ll also dig into error handling options.

What is a callback?

As we’ve seen in the previous posts in this series, our entire grammar is built directly in C# or VB code.  We do not do code generation like a lot of other parser generators do.  A benefit of this is that you can interact directly with objects in the grammar.  More...

SyntaxEditor grammar/AST framework part 5: Optimizing the Simple grammar’s AST output

by Bill Henning (Actipro) August 11, 2010 at 01:04

In the previous post we gave an introduction to the powerful tree construction mechanism that is built into the grammar/AST framework and talked about each of the built-in tree construction nodes that are available.  We also mentioned that for very rare scenarios where advanced logic is needed to build a particular AST node, you can create and inject your own ITreeConstructionNode-based classes to handle the task.

In today’s post, we’re going to revisit the Simple language and will enhance our grammar productions so that we make the resulting AST very concise.  More...

SyntaxEditor grammar/AST framework part 4: Introduction to customizing tree construction

by Bill Henning (Actipro) August 10, 2010 at 01:00

In the previous post of this series, we walked through how to create a grammar for the Simple language (which is similar to a Javascript subset) using our new grammar/AST framework.  We showed how easy it was to write the grammar using EBNF-like notation but completely from within your native C#/VB code.

We also showed how the grammar automatically generates an AST of the parsed document for you.  The generated tree generally has much more information than what is useful though.  Today’s post is going to show how we can completely customize the AST output so that it focuses only on the information we care about.

Our grammar/AST framework has an extremely powerful tree construction mechanism with numerous built-in helper methods to do common tree construction tasks.  You also have the ability to create completely custom tree construction nodes via C#/VB code if you like.

Default tree construction

The default tree constructors will output nearly everything that is parsed.  Each AST node that is generated automatically contains the offset range of the text that created it.  More...

SyntaxEditor grammar/AST framework part 3: Creating a grammar for the Simple language

by Bill Henning (Actipro) August 9, 2010 at 01:20

In the previous post we gave a detailed introduction to symbols, EBNF terms, and how you can translate a language’s EBNF specification to our grammar framework.

In today’s post we’re going to write a C#-based grammar using our new framework for a language called Simple.  The Simple language is basically a small subset of a Javascript-like language.  When we’re done, we’ll load it up into a SyntaxEditor and will look at the AST results that are generated for us based on some input code.

Finding the language specification

The first thing to do when building a Grammar for a language is to locate the language specification for the language.  Nearly all programming languages have some sort of formal EBNF specification that tell parsers and compilers how to interpret their code.  More...

SyntaxEditor grammar/AST framework part 2: Introduction to symbols and EBNF terms

by Bill Henning (Actipro) August 6, 2010 at 01:37

In the previous post, we gave an overview about what we’ll be covering in this multi-part walkthrough of the next generation grammar/AST framework we’re developing for SyntaxEditor, our code editor control.

Today’s post will dive right into a grammar and the building blocks needed to create one.

Grammar

A grammar is a set of production rules for parsing text in a formal language, where there is a single starting symbol from which parsing should begin.  All code languages should have some sort of EBNF grammar specification available for reference on the Internet, so that compilers and other products know how to read the code and interpret it.

Symbols

A grammar is comprised of symbols, which are either terminals or non-terminals.

Terminals are the lowest-level fixed-input lexical element used in a grammar production rule.  In the case of SyntaxEditor’s framework, terminals equate to tokens that are read in from a lexer.

NonTerminals each have a production rule, that is comprised of some combination of terminal and non-terminal symbol references.

EBNF sample

Take this EBNF for a Simple language FunctionDeclaration non-terminal:

   1: FunctionDeclaration:
   2:     "function" "identifier" "(" FunctionParameterList? ")" Block

That is saying the non-terminal’s name is FunctionDeclaration and a function declaration is built by a concatenation of a function terminal, followed by an identifier terminal, followed by an open parenthesis terminal, followed by an optional FunctionParameterList non-terminal, followed by a close parenthesis terminal, and ending with a Block non-terminal.  More...