Annoying syntactical exceptions

So I have been writing these Pass#1 statement parsers for a while now (a bit more than 20 more to go). Recently, I came across with the Declare Function statement. It’s responsible for declaring a function from an outside resource – for example, a DLL-file. The general guideline is that all statements would look the same as the corresponding statement in VB.NET. So I began the normal procedure I do with every new statement parser, i.e type in a sample code in a source file which will then be passed to the compiler. Now, the first thing to do is to enable the parser function in question and then create the parser skeleton for quick OK check. I was surprised to notice that the compilation failed due to syntax error before the code line got even passed to the main parser function. The VB.NET syntax is as follows:

Declare Function MyFunc Lib "System.DLL" Alias "_RealFunctionName" ( [params] ) As [type]

Now the general syntax rules define that a literal cannot appear just before an opening parenthesis. And well well, isn’t that a string literal and a parameter list just after. I was first like, WTF how can I “fix” this in a non-ugly way without breaking the general syntax rule set. I had three choises, none of which seemed good way to go:

  1. Allow a string literal to precede an opening parenthesis
  2. Allow a string literal to precede an opening parenthesis only in a Declare statement
  3. Alter the syntax of the Declare statement

Definately not Option 1. Option 2 seemed to be the best choise because I still did’t want to alter the syntax of the statement. But that would have been an exception to the syntax rules. I don’t like exceptions in any program structure, because in the end, it will make code maintenance messed up. I thought about pros and cons of options 2 & 3 for a long time. I could have added a small keyword between the string literal and parameter list. The resulting statement syntax could look something like this:

Declare Function MyFunc Lib "System.DLL" Alias "_RealFunctionName" Ansi ( [params] ) As [type]

…where “Ansi” could be, for example, a charset modifier (Ansi/Unicode/Auto). On the other hand, charset modifier is already an optional modifier in the VB.NET syntax; its place is right after the Declare keyword. CoolBasic won’t provide support for charset modifiers just yet (since it’s optional I can add it later on without breaking all existing CoolBasic source codes which would make users angry).

Another solution for Option 3 would be to define Alias as identifier instead of a string. The syntax would look something like this:

Declare Function MyFunc Lib "System.DLL" Alias _RealFunctionName ( [params] ) As [type]

It seemed like a good idea at first, but come to think about it the solution would be logically wrong. By definition, all identifiers should be usable by the programmer. In this case, the Alias identifier would not – or it would be unintended identifier reserving a name without real operational use. At this point I ran out of options. This isn’t by the best practise, but I decided to go for Option 2. Luckily I’ve designed the lexer to be quite flexible so I only needed a small change in one place, basically overriding a syntax error based on a simple condition of few preceding line tokens.

As a result, the syntax will be exactly like in VB.NET, as intended. Internally, the fix didn’t end up being as ugly as I had feared. Overall, I’m content with the outcome. Pass#1 continues…

Comments are closed.

Copyright © All Rights Reserved · Green Hope Theme by Sivan & schiy · Proudly powered by WordPress