Trouble Adding UserDefinedLanguage Parser to NotePad++ v6.8.2



  • Hi all,

    I’m attempting to add a User Defined Language parser to the functionsList.xml file and have created the required regexes, which I’ve validated with RegexBuddy using a language text file, as follows:

    In the <associationMap> section, i’ve have added:

    <association userDefinedLangName=“EasyLanguage” id=“ts_elang_function”/>

    And in the <parsers> section, i have added a new parser section, like so:

    		<parser id="ts_elang_function" displayName="TSEL" commentExpr="((//.*?$)">
    			<!-- Only match nodes with at least one attribute -->
    			<function
    			    mainExpr="(.*)?(?i:method\s)+(?i:(void|double|bool|int)\s)+([_a-zA-Z0-9]+)\s*(\(.*\)\n|[\(][_a-zA-Z0-9]+[\)]\n|\([^()]*[\)][\n])"
    				displayMode="$functionName">
    				<functionName>
    					<nameExpr expr="(.*)"/>
    				</functionName>
    			</function>
    		</parser>
    

    Here’s a sample of a language file for testing:
    //------------------------------------------------------------------------
    method double UpdateExitVaRShQTY(string StratDuration)
    vars: double x;
    begin
    return x;
    end;

    Method int SharesToBuy()
    Vars: int XXX, string DurTrade, double StopOffsetVal;
    Begin
    StopOffsetVal = 0;
    If chkbxVaRSize.Checked Then
    Begin
    If cbxDurTgtsStop.Text <> " Not Set…" Then
    Begin
    DurTrade = cbxDurTgtsStop.Text;
    Print("Trade Duration: " + DurTrade);
    Switch (DurTrade)
    Begin
    Case " Day Trade ": //Note: <sp>String<sp>
    If strtonum(cbxStpLossOffset.Text) <> 0 Then
    StopOffsetVal = ThisATR * strtonum(cbxStpLossOffset.Text) astype double; //Alt_DayATRStpLoss;
    Print("Day StopLoss Offset: " + cbxStpLossOffset.Text);
    Case " Mini-Swing ":
    StopOffsetVal = ThisATR * strtonum(cbxStpLossOffset.Text) astype double; // Alt_MiniATRStpLoss;
    Print("Mini-Swing StopLoss Offset: " + cbxStpLossOffset.Text);
    Case " Swing ":
    StopOffsetVal = ThisATR * strtonum(cbxStpLossOffset.Text) astype double; // Alt_SwingATRStpLoss;
    Print("Swing StopLoss Offset: " + cbxStpLossOffset.Text);
    End;
    Print("Computed StopOffset Value: " + numtostr(StopOffsetVal,2));
    If StopOffsetVal <> 0 Then
    XXX = Round((strtonum(updEntryShares.Text) astype double / StopOffsetVal), 0) astype int
    Else XXX = 0 astype int;
    End;
    End
    Else XXX = strtonum(updEntryShares.Text) astype int;
    Return XXX;
    End;

    Method void GAPEntryLogic()
    Vars: double x;
    begin

    end;

    method double GetNextFTP(int UpDown, double RefMaxPrice, double RefMinPrice, out string FTPSelstr)
    vars: double x;
    begin
    return x;
    end;

    Method void ORState(out datetime BreakdownDT,
    out bool BreakdownFlag,
    out int BreakdownState,
    out datetime DTBreakout,
    out bool BreakoutFlag,
    out int BreakoutState,
    in double Price,
    in double ORHigh,
    in double ORLow,
    in double ATRNow,
    in double ThisPcntATR )
    vars: double x;
    begin

    end;

    Method bool Set2MinORState()
    Vars: bool x;
    begin
    return x;
    end;
    //------------------------------------------------------------------------

    The above parser is intended to list the methods declared with their input args string. I have defined a user-define language named EasyLanguage. This works and formats the above text file beautifully. However, my above added parser doesn’t appear to do anything. It just lists the file name in the displayed Function List and that’s it. No methods are being parsed. The functionlist.xml file is located in the same directory as the main NotePad++ executable. I’ve done my best to follow the online guide provided at: https://notepad-plus-plus.org/features/function-list.html.

    I see no errors being thrown, so I am not sure what i’m doing incorrectly.

    If someone could kindly take a look at what i’ve done here and advise as to what i’m doing incorrectly with this parser, I’d be deeply appreciative.

    Thanks much.

    Best Regards,
    Jean-Claude



  • Hi all,

    My apologies for inquiring again.

    Can anyone confirm whether this user definable parser feature as presented at https://notepad-plus-plus.org/features/function-list.html has been tested and implemented by anyone for any UserDefinedLanguage? The reason I ask is because the only thing that seems to work are the internally supported languages.

    A small working example along with a small snippet of the language syntax in question that illustrates how they implemented their class and/or function name parser in the functionList.xml file would be deeply appreciated.

    Thanks,
    Jean-Claude



  • If I remember correctly there is a problem with UDL association, use a file extension association instead.



  • Hello, thanks for the kind reply.

    I think I’m about ready to punt on this. I tried the following:

    		<association ext=".eltxt" id="ts_easylang"/
    

    so that the entire <association map then looked like this:

    	<associationMap>
    	<!-- langID:
    		L_TEXT: 0     L_PHP: 1        L_C: 2        L_CPP: 3       L_CS: 4         L_OBJC: 5
    		L_JAVA: 6     L_RC: 7         L_HTML: 8     L_XML: 9       L_MAKEFILE: 10  L_PASCAL: 11
    		L_BATCH:12    L_INI: 13       L_ASCII: 14   L_USER: 15     L_ASP: 16       L_SQL: 17
    		L_VB: 18      L_JS: 19        L_CSS: 20     L_PERL: 21     L_PYTHON: 22    L_LUA: 23
    		L_TEX: 24     L_FORTRAN: 25   L_BASH: 26    L_FLASH: 27    L_NSIS: 28      L_TCL: 29
    		L_LISP: 30    L_SCHEME: 31    L_ASM: 32     L_DIFF: 33     L_PROPS: 34     L_PS: 35
    		L_RUBY: 36    L_SMALLTALK:37  L_VHDL: 38    L_KIX: 39      L_AU3: 40       L_CAML: 41
    		L_ADA: 42     L_VERILOG: 43   L_MATLAB: 44  L_HASKELL: 45  L_INNO: 46      L_SEARCHRESULT: 47
    		L_CMAKE: 48   L_YAML: 49      L_COBOL 50    L_GUI4CLI: 51  L_D: 52         L_POWERSHELL: 53
    		L_R: 54       L_JSP: 55
    	-->
    		<association langID="1" id="php_function"/>
    		<association langID="2" id="c_function"/>
    		<association langID="3" id="c_cpp_function"/>
    		<association langID="4" id="cs_function"/>
    		<association langID="6" id="java"/>
    		<association langID="9" id="xml_node"/>
    		<association langID="12" id="batch_label"/>
    		<association langID="13" id="ini_section"/>
    		<association langID="19" id="js_function"/>
    		<association langID="21" id="perl_function"/>
    		<association langID="22" id="python_function"/>
    		<association langID="26" id="bash_function"/>
    		<association langID="28" id="nsis_syntax"/>
    		<association ext=".eltxt" id="ts_easylang"/>
    	<!--
    		Previous attempt at associating my parser... 
    		<!-- <association userDefinedLangName="EasyLanguage" id="ts_easylang"/> 
    					
    		if langID cannot be found above, you can still set the file extensions
    		<association ext=".my_passer_ext1" id="my_passer_id"/>
    		<association ext=".my_passer_ext2" id="my_passer_id"/>
    		
    		for User Defined Languages:
    		<association userDefinedLangName="my user defined language" id="my_udl_passer_id"/>
    		<association userDefinedLangName="Autocad" id="my_autocad_passer_id"/>
    	-->
    
    	</associationMap>
    

    I then also changed the file extension specified under Language>Define your language… selected my defined language, EasyLanguage in this case, and then specified the file extension to “.eltxt”, first with w/o the .dot, then with the .dot, and with and w/o the double quotes. It made no difference.

    For testing, i created the following test language syntax file and named it Test.eltext:


    method double UpdateExitVaRShQTY(string StratDuration)
    vars: double x;
    begin
    return x;
    end;

    Method int SharesToBuy()
    Vars: int XXX, string DurTrade, double StopOffsetVal;
    Begin
    StopOffsetVal = 0;
    If chkbxVaRSize.Checked Then
    Begin
    If cbxDurTgtsStop.Text <> " Not Set…" Then
    Begin
    DurTrade = cbxDurTgtsStop.Text;
    Print("Trade Duration: " + DurTrade);
    Switch (DurTrade)
    Begin
    Case " Day Trade ": //Note: <sp>String<sp>
    If strtonum(cbxStpLossOffset.Text) <> 0 Then
    StopOffsetVal = ThisATR * strtonum(cbxStpLossOffset.Text) astype double; //Alt_DayATRStpLoss;
    Print("Day StopLoss Offset: " + cbxStpLossOffset.Text);
    Case " Mini-Swing ":
    StopOffsetVal = ThisATR * strtonum(cbxStpLossOffset.Text) astype double; // Alt_MiniATRStpLoss;
    Print("Mini-Swing StopLoss Offset: " + cbxStpLossOffset.Text);
    Case " Swing ":
    StopOffsetVal = ThisATR * strtonum(cbxStpLossOffset.Text) astype double; // Alt_SwingATRStpLoss;
    Print("Swing StopLoss Offset: " + cbxStpLossOffset.Text);
    End;
    Print("Computed StopOffset Value: " + numtostr(StopOffsetVal,2));
    If StopOffsetVal <> 0 Then
    XXX = Round((strtonum(updEntryShares.Text) astype double / StopOffsetVal), 0) astype int
    Else XXX = 0 astype int;
    End;
    End
    Else XXX = strtonum(updEntryShares.Text) astype int;
    Return XXX;
    End;

    Method void GAPEntryLogic()
    Vars: double x;
    begin

    end;

    method double GetNextFTP(int UpDown, double RefMaxPrice, double RefMinPrice, out string FTPSelstr)
    vars: double x;
    begin
    return x;
    end;

    Method void ORState(out datetime BreakdownDT,
    out bool BreakdownFlag,
    out int BreakdownState,
    out datetime DTBreakout,
    out bool BreakoutFlag,
    out int BreakoutState,
    in double LastPrice},
    in double ORHigh,
    in double ORLow,
    in double ATRNow,
    in double ThisPcntATR )
    vars: double x;
    begin

    end;

    Method bool Set2MinORState()
    Vars: bool x;
    begin
    return x;
    end;


    And the UDL parser section I added looks like this:

    		<parser id="ts_easylang" displayName="EasyLanguage" commentExpr="({[^()]*?})|(//.*?\r\n)">
    			<function
    			    mainExpr="(.*)?(?i:method\s)+(?i:(void|double|bool|int)\s)+([_a-zA-Z0-9]+)\s*(\(.*\)\r\n|[\(][_a-zA-Z0-9]+[\)]\r\n|\([^()]*[\)][\r\n])"
    				displayMode="$functionName">
    				<functionName>
    					<nameExpr expr="(.*)?(?i:method\s)+(?i:(void|double|bool|int)\s)+([_a-zA-Z0-9]+)\s*(\(.*\)\r\n|[\(][_a-zA-Z0-9]+[\)]\r\n|\([^()]*[\)][\r\n])"/>
    					<!-- <nameExpr expr="([_a-zA-Z0-9]+)\s*(\(.*\)\r\n|[\(][_a-zA-Z0-9]+[\)]\r\n|\([^()]*[\)][\r\n])"/> -->
    				</functionName>
    			</function>
    		</parser>
    

    … but nothing still displays under the Function List tab. Unless I am misunderstanding something (which is possible), i’m starting to think that this feature is completely broken and I’d love to be able to fix it! I’m just not sure where to start looking in the source code.

    Has anyone actually had any luck getting a UDL function list parser to work in their NotePad++ setup???

    Thanks much,
    Jean-Claude



  • Hi all,

    This feature is clearly broken.

    I sent a bug report to Don but never got a response.

    Would love to fix this. If anyone here is familiar with the source code for NP++, feel free to message me. Am happy to work on this.

    Thanks,
    Integrion



  • Try the following FunctionList association & parser and make sure you have the UDL defined. The UDL can be ‘empty’ i.e. only name (EasyLanguage) and extension (eltxt, no leading dot) defined.

          <association ext=".eltxt" userDefinedLangName="EasyLanguage" id="ts_easylang"       />
    
          <parser
              id         ="ts_easylang"
              displayName="EasyLanguage"
              commentExpr="({[^{}]*?})|(//.*?$)"
            >
            <function
                mainExpr="(?i)METHOD\s+(?-i:void|double|bool|int)\s+(?'NAME'\w+)\s*(?'ARGS'\([^()]*\))(?:\r?\n|\r)"
              >
              <functionName>
                <nameExpr expr="(?i)METHOD\s+\K[^)]+\)" />
                <!-- comment out the following node to display the method with its parameters -->
                <nameExpr expr="[^(]+" />
              </functionName>
            </function>
          </parser>
    

Log in to reply