T-SQL variables

Jul 30, 2015 at 10:20 AM
Edited Jul 30, 2015 at 10:29 AM
Hello, I need to distinguish between some other Ids and T-SQL variables. No matter what I do, by modifying the SQL example, I can't make it work. It confuses local and global variables, and when I get these right, it thinks 3 is a local variable.

How could it be modified the SQL grammar example in order to detect local variables (prefixed by @), global ones (prefixed by @@) and other things, like numbers (for example 3)? Note that is allowed to have local variables as @3. Thank you.
Coordinator
Jul 31, 2015 at 10:34 PM
You can do the following. Declare one IdentifierTerminal named genericNameTerm and add @ to first-char list; make it high priority. This is the one that will be actually scanning the input.
Declare 3 more 'specialized' terminals, each for one of subtypes: nameTerm, localVarTerm and globalVarTerm. Leave priority as is (default). Hook to genericNameTerm.ValidateToken event. In the event handler analyze the identifier string, and replace the Terminal property of the token with the appropriate specialized terminal. Use specialized terminals in grammar rules, but add genericNameTerm to NonGrammarTerminals list.
My guess is this should work.
Aug 5, 2015 at 11:26 AM
Edited Aug 6, 2015 at 8:07 AM
Do you have some example of ValidateToken event?
And what do you mean by "subtype"? Is there a relation between the subtypes and the genericNameTerm in terms of method call or property assignment?
I try to get directly identifiers like "id" or variables like "@id" or "@@servername". Additionally, I will have to do the same for temporary tables, prefixed by "#" or "##".
Aug 7, 2015 at 10:19 AM
IMHO, being just a newbie, I think the prefixes should be also strings, not characters only. In this case, if I want to limit the characters of the prefix to '@', which is 'UnicodeCategory.OtherPunctuation', AKA 'Po', the second '@' will throw an error due to excluding 'UnicodeCategory.OtherPunctuation' from the identifier's body.
Aug 7, 2015 at 12:42 PM
I have declared an IdentifierTerminal named genericNameTerm and have added '@' to first-char list. Adding it to NonGrammarTerminals list blows into the error 'A terminal id_var_global has empty prefix.' because IdentifierTerminal defines GetFirsts() as:
public override IList<string> GetFirsts() {
      // new scanner: identifier has no prefixes
      return null; 
/*
      var list = new StringList();
      list.AddRange(Prefixes);
      foreach (char ch in _allFirstCharsSet)
        list.Add(ch.ToString());
      if ((Options & IdOptions.CanStartWithEscape) != 0)
        list.Add(this.EscapeChar.ToString());
      return list;
 */
    }