Assume one wants to create a simple .NET language, or slightly more difficult, a compiler for an existing .NET language. Do you absolutely need to be familiar with the CIL (Common Intermediate Language) to implement a compiler? And do you have to translate the syntax of your language to CIL by hand? Or is there another (more preferable) way? If not, what is the best way to learn CIL and especially to learn how to translate High-Level code to CIL?
C# Compiler – Do You Need to Know CIL to Make a Compiler for .NET?
ccompilermanaged-codenetprogramming-languages
Related Solutions
This is going to be a large and very involved project. I've been responsible for migrating Access databases to .NET many times, but never on this scale. I agree that a gradual approach will probably be the most realistic. Trying to take on everything in one shot is an easy way to fail.
As in other answers, the first and most important step will be to move everything to SQL Server. While doing this, document the database if this hasn't already been done, and identify areas for refactoring if they exist. Access databases that grow to meet evolving needs often have data models that can be improved upon when looking at the big picture.
Next, identify modules of the application that are "self contained". Because this is a do-everything database, there will probably be modules of it that are nearly completely disjoint from each other. After having these disjoint pieces, identify one of the smaller modules that has the most to gain from being updated, and take it on first.
While migrating to .NET, don't just do a simple 1 to 1 copy of the application. Gather input from users to identify pain points with the current application. You want your first migration unit to be a huge success to gain the complete buy in from everyone else.
After you have the first unit done, look at what happened in terms of challenges, difficulties, etc, and use this moving forward.
One thing that I would strongly discourage would be to implement partially working modules (ex: "we migrated the CRM, but features X,Y,Z are not in the new system yet"). This will cause users to quickly become frustrated from having an incomplete system when the old one to them was "perfectly fine". This kind of development may work fine for other domains, but not in businesses where users see "nothing wrong" with the old Access monolith and don't understand the migration needs.
Predictive parser you selected (LL(k)) means you will have to solve left-recursion problems. Algorithm for solving direct and indirect recursions is clearly described on wikipedia:
http://en.wikipedia.org/wiki/Left_recursion
Some info can be found in posts here on StackOverflow:
https://stackoverflow.com/questions/2652060/removing-left-recursion https://stackoverflow.com/questions/2999755/removing-left-recursion-in-antlr https://stackoverflow.com/questions/4994036/left-recursion-elimination
In human language (non-scientific :) "left-recursion problem" means you can't endlessly go into recursion with non-terminal (A -> Ab) again and again. At some time you HAVE TO feed parser algorithm with a terminal to breake a loop.
In BNF this could look like:
Recursion Problem:
NT: NT T
NT: T
One solution:
NT: T NT2
NT2: T NT2
NT2:
For your grammar this could look like:
DataType:
PrimitiveDataType ArrayDimensions
| ComplexDataType ArrayDimensions
ArrayDimensions:
[] ArrayDimensions
|
If your parser generator doesn't allow empty productions and/or if you want to process array types separately, try something like this:
DataType:
DataTypeName
| ArrayDataType
ArrayDataType:
DataTypeName ArrayDimensions
DataTypeName:
PrimitiveDataType
| ComplexDataType
ArrayDimensions:
[]
| [] ArrayDimensions
Best Answer
Of course you can generate C# or any other higher level language code instead of targeting CIL directly.
It is common to implement compilers as eDSLs on top of meta-languages. You can take, say, a decent Scheme implementation for .NET, or a more heavyweight language, like Nemerle, and build up your compiler as a set of macros on top of a host language, with a syntax front-end at the very top of this hierarchy.
As you've mentioned "translating the syntax to CIL", you're likely having a somewhat distorted view on how compilers should work. Normally there are many more steps in between parser and code generation, and it does not make any sense to do everything in a single pass.
And, of course, if your language semantics is significantly different from the host language, for an efficient implementation you'd still be much better off with generating CIL directly (or via a sequence of intermediate languages).
Learning CIL is not a big deal at all: everything you have to know is available on MSDN.
And here is a trivial example of building a compiler on top of a meta-language - you can easily do it with any Lisp.