test

Home Forums General Test Me test

This topic contains 0 replies, has 6,314 voices, and was last updated by  deleyd 10 years, 5 months ago.

Viewing 1 post (of 1 total)
  • Author
    Posts
  • #2168

    deleyd
    Participant

    Adding Language Support 4: Construct Matching

    Construct Matching allows the matching up of corresponding keywords, such as IF…ENDIF, LOOP…END LOOP, BEGIN…END, CASE…END CASE, #IFDEF…#ENDIF, DO…WHILE, RECORD…END RECORD, REPEAT…UNTIL, SELECT CASE…END SELECT, FUNCTION…END FUNCTION, MODULE…ENDMODULE.

    Construct Matching also allows the matching up of corresponding parentheses, which can be helpful when examining a statement with numerous nested parentheses. For example, position your cursor on an opening parenthesis "(", press Ctrl+F9, and the cursor will find the matching closing parenthesis ")", taking into account all nested parentheses, skipping over any parentheses that are inside comments and hence don’t count. You can also search for matching brackets { } and [ ] if your language uses them.

    Below we will create/modify the following 3 macros:[list:3hus9ax1][*:3hus9ax1]AwkMatchInit[/*:m:3hus9ax1][*:3hus9ax1]AwkInit[/*:m:3hus9ax1][*:3hus9ax1]_AwkGetMatchPat[/*:m:3hus9ax1][/list:u:3hus9ax1]
    The AwkMatchInit macro
    We need to create a <lang>MatchInit macro for our language which defines all the matching constructs. For Awk our macro will be AwkMatchInit. The macro itself creates three global variables:

      [*:3hus9ax1]!AwkMatchExtra[/*:m:3hus9ax1]
      [*:3hus9ax1]!AwkMatchBegPat[/*:m:3hus9ax1]
      [*:3hus9ax1]!AwkMatchEndPat[/*:m:3hus9ax1][/list:o:3hus9ax1]Following is an example of a <lang>MatchInit macro. We’ll go over the various parts below. (Note: this is not the actual one used for Awk, it’s just a demo):

      [code:3hus9ax1]void AwkInitMatch( )
      {
      if ( Length( Global_Str( "!AwkMatchExtra" ) ) == 0 ) {

      //********** SET WORD BEGIN/END CHARACTERS AND DELIMITER **********
      Set_Global_Str( "!AwkMatchExtra",
      _mtchBChars + _c_whitespace +
      _mtchEChars + _c_whitespace +
      _mtchDelim + " " );
      _mtchPerlRE + "0" );

      //********** SET BEGIN CONSTRUCT PATTERNS **********
      Set_Global_Str( "!AwkMatchBegPat",

      _mtchSep + "(" +
      _mtchFlags + str(_mcf_StrOnly) +
      _mtchBeg + " ( " +
      _mtchMid + "" +
      _mtchEnd + " ) " +
      _mtchExp + "[()]" +

      _mtchSep + "WHILE" +
      _mtchFlags + "0" +
      _mtchBeg + " WHILE " +
      _mtchMid + "" +
      _mtchEnd + " ENDWHILE " +
      _mtchExp + "(ENDWHILE)|(WHILE)" +

      _mtchSep );

      //********** SET END CONSTRUCT PATTERNS **********
      Set_Global_Str( "!AwkMatchEndPat",

      _mtchSep + ")" +
      _mtchFlags + str(_mcf_StrOnly) +
      _mtchBeg + " ) " +
      _mtchEnd + " ( " +
      _mtchExp + "[()]" +

      _mtchSep + "ENDWHILE" +
      _mtchFlags + "0" +
      _mtchBeg + " ENDWHILE " +
      _mtchEnd + " WHILE " +
      _mtchExp + "(WHILE)|(ENDWHILE)" +

      _mtchSep );
      }
      }
      [/code:3hus9ax1]

      !AwkMatchExtra
      The !AwkMatchExtra global variable has the following form:
      [code:3hus9ax1]//********** SET WORD BEGIN/END CHARACTERS AND DELIMITER **********
      Set_Global_Str( "!AwkMatchExtra",
      _mtchBChars + _c_whitespace +
      _mtchEChars + _c_whitespace +
      _mtchDelim + " ",
      _mtchPerlRE + "0" );
      [/code:3hus9ax1][list:3hus9ax1][*:3hus9ax1]_mtchBChars — Beginning Chars. A list of characters that can precede a construct word. Often whitespace is all you need to specify here, but you can add more characters if needed. (_c_whitespace = space, tab, virtual space.)[/*:m:3hus9ax1]
      [*:3hus9ax1]_mtchEChars — Ending Chars. A list of characters that can follow a construct word. Often whitespace is all you need to specify here, but you can add more characters if needed. (_c_whitespace = space, tab, virtual space.)
      (Parsing off of keywords is a bit complicated. See the outline at the beginning of AwkInitMatch in Awk.s (attached). You only need to study this if you are having problems.)[/*:m:3hus9ax1]
      [*:3hus9ax1]_mtchDelim — The delimiter used in the following !<lang>MatchBegPat and !<lang>MatchEndPat globals. Set this to a space character " " unless you have keywords which include a space, such as "END IF" or "END DO", in which case set this to the vertical bar character "|".[/*:m:3hus9ax1]
      [*:3hus9ax1]_mtchPerlRE — Set to "1" if you want to use Perl regular expressions instead of UNIX regular expressions in _mtchExp (below). (This parameter may be omitted if you wish to default to UNIX regular expressions.)[/*:m:3hus9ax1][/list:u:3hus9ax1]

      !AwkMatchBegPat
      Here’s a short example of a !<lang>MatchBegPat global variable with comments. This example sets up matching for parentheses and WHILE…ENDWHILE:
      [code:3hus9ax1]//..v....1....v....2....v....3....v....4....v....50...v....6....v....7....v....8
      //********** SET BEGIN CONSTRUCT PATTERNS **********
      Set_Global_Str( "!AwkMatchBegPat",

      _mtchSep + "(" + // ( matching
      _mtchFlags + str(_mcf_StrOnly) + /* Flags = 1. Match character */
      _mtchBeg + " ( " + /* construct begins with ( */
      _mtchMid + "" + /* (don’t care what’s in the middle) */
      _mtchEnd + " ) " + /* construct ends with ) */
      _mtchExp + "[()]" + /* UNIX regular expression.
      Search for closing )
      or opening ( of a nested construct */

      _mtchSep + "WHILE" + // WHILE...ENDWHILE matching
      _mtchFlags + "0" + /* Flags = 0. Match keyword */
      _mtchBeg + " WHILE " + /* construct begins with WHILE */
      _mtchMid + "" + /* (don’t care what’s in the middle) */
      _mtchEnd + " ENDWHILE " + /* construct ends with ENDWHILE */
      _mtchExp + "(ENDWHILE)|(WHILE)" + /* UNIX regular expression.
      Search for ENDWHILE or nested WHILE */

      _mtchSep );
      [/code:3hus9ax1](Note: This is not the code actually used for Awk.)

      !AwkMatchEndPat
      And here’s a corresponding example of a !<lang>MatchEndPat global variable with comments. Note how these correspond to the ones defined above for our !<lang>MatchBegPat. (Remember for this we are searching backwards, so we begin at the end and end at the beginning):
      [code:3hus9ax1]//..v....1....v....2....v....3....v....4....v....50...v....6....v....7....v....8
      //********** SET BEGIN CONSTRUCT PATTERNS **********
      Set_Global_Str( "!AwkMatchEndPat",

      _mtchSep + ")" + // ) matching
      _mtchFlags + str(_mcf_StrOnly) + /* Flags = 1. Match character */
      _mtchBeg + " ) " + /* construct begins with ) */
      _mtchEnd + " ( " + /* construct ends with ( */
      _mtchExp + "[()]" + /* UNIX regular expression.
      Search for closing )
      or opening ( of a nested construct */

      _mtchSep + "ENDWHILE" + // WHILE...ENDWHILE matching
      _mtchFlags + "0" + /* Flags = 0. Match keyword */
      _mtchBeg + " ENDWHILE " + /* construct begins with ENDWHILE */
      _mtchEnd + " WHILE " + /* construct ends with WHILE */
      _mtchExp + "(WHILE)|(ENDWHILE)" + /* UNIX regular expression.
      Search for WHILE or nested ENDWHILE */

      _mtchSep );
      [/code:3hus9ax1](Note: This is not the code actually used for Awk.)

      I placed numerous examples in InitMatchBeg_examples.s and InitMatchEnd_examples.s (in the "InitMatch_examples.zip" file attached). Have a look at those two files. You’ll probably find what you want to match is already in those example files.

      The AwkInit Macro
      We need to add a line of code to our AwkInit macro which calls AwkInitMatch:
      [code:3hus9ax1]void AwkInit( )
      {
      // Initialize construct matching patterns
      AwkInitMatch( );
      }
      [/code:3hus9ax1]

      The _AwkGetMatchPat Macro
      And we need to add a _AwkGetMatchPat macro. The _AwkGetMatchPat macro in Ada1.s is generic and works for most languages. Just copy this macro.

      Awk1.s
      Our resulting Awk1.s file is attached. Notice the order of the macros in the file. We want macros which get called go above macros which call them, so we don’t have to prototype them. Here I am just duplicating the standard order found in Ada.s and all the other language specific support files.

Viewing 1 post (of 1 total)

You must be logged in to reply to this topic.