Menu

Subclassing yyFlexLexer

2014-12-01
2014-12-19
  • walshy002000

    walshy002000 - 2014-12-01

    Hi Everyone,

    So after fixing up my previous problem a while back for VS integration, I'm now trying to figure out how to subclass yyFlexLexer with class 'S' and have flex generate the appropriate S::yylex() calls. From the flex manual (http://flex.sourceforge.net/manual/Cxx.html):

    "If you derive a subclass S from yyFlexLexer and want to access the member functions and variables of S inside yylex(), then you need to use %option yyclass="S" to inform flex that you will be using that subclass instead of yyFlexLexer. In this case, rather than generating yyFlexLexer::yylex(), flex generates S::yylex() (and also generates a dummy yyFlexLexer::yylex() that calls yyFlexLexer::LexerError() if called). "

    How do I perform the
    %option yyclass="S"
    action in VS with the current build approach?

    Thanks in advance,
    James

     
    • Alex Zhondin

      Alex Zhondin - 2014-12-01

      Hi James,

      I believe you can add "--yyclass=S" option to "Command Line"->"Additional Options" of the flex file properties dialog. There you can add any options you need that not listed in "Flex Options".

      If you want to have such option in "Flex Options" section I will add it.

      Best regards,
      Alex

       
  • walshy002000

    walshy002000 - 2014-12-04

    Hi Alex,

    Admittedly I'm fairly new to flex, but I think I've done that correctly but I'm still getting linking errors for missing functions - which I think is because they're missing the custom prefix. I've attached a screenshot of my command line config for the .l file.

    Basically I'm porting a two libraries A and B. A has the actual use of Flex in a wrapper then used in B. What's odd, is I can compile A as a static library ok, but when I go to include it in B and build, I get the following linker errors:

    Error 24 error LNK2019: unresolved external symbol "public: thiscall OBJFormatScanner_yyFlexLexer::OBJFormatScanner_yyFlexLexer(class std::basic_istream<char,struct std::char_traits<char=""> > ,class std::basic_ostream<char,struct std::char_traits<char=""> > )" (??0OBJFormatScanner_yyFlexLexer@@QAE@PAV?$basic_istream@DU?$char_traits@D@std@@@std@@PAV?$basic_ostream@DU?$char_traits@D@std@@@2@@Z) referenced in function "public: thiscall wcl::OBJFormatScanner::OBJFormatScanner(class std::basic_istream<char,struct std::char_traits<char=""> > ,class std::basic_ostream<char,struct std::char_traits<char=""> > )" (??0OBJFormatScanner@wcl@@QAE@PAV?$basic_istream@DU?$char_traits@D@std@@@std@@PAV?$basic_ostream@DU?$char_traits@D@std@@@3@@Z) E:\Documents\WCLDriver\libSAR\libWCLVS.lib(OBJParser.obj) libSAR
    Error 25 error LNK2019: unresolved external symbol "public: virtual thiscall OBJFormatScanner_yyFlexLexer::~OBJFormatScanner_yyFlexLexer(void)" (??1OBJFormatScanner_yyFlexLexer@@UAE@XZ) referenced in function "public: virtual thiscall wcl::OBJFormatScanner::~OBJFormatScanner(void)" (??1OBJFormatScanner@wcl@@UAE@XZ) E:\Documents\WCLDriver\libSAR\libWCLVS.lib(OBJParser.obj) libSAR
    Error 26 error LNK2001: unresolved external symbol "public: virtual void thiscall OBJFormatScanner_yyFlexLexer::yy_switch_to_buffer(struct yy_buffer_state *)" (?yy_switch_to_buffer@OBJFormatScanner_yyFlexLexer@@UAEXPAUyy_buffer_state@@@Z) E:\Documents\WCLDriver\libSAR\libWCLVS.lib(OBJParser.obj) libSAR
    Error 27 error LNK2001: unresolved external symbol "public: virtual struct yy_buffer_state *
    thiscall OBJFormatScanner_yyFlexLexer::yy_create_buffer(class std::basic_istream<char,struct std::char_traits<char=""> > ,int)" (?yy_create_buffer@OBJFormatScanner_yyFlexLexer@@UAEPAUyy_buffer_state@@PAV?$basic_istream@DU?$char_traits@D@std@@@std@@H@Z) E:\Documents\WCLDriver\libSAR\libWCLVS.lib(OBJParser.obj) libSAR
    Error 28 error LNK2001: unresolved external symbol "public: virtual void thiscall OBJFormatScanner_yyFlexLexer::yy_delete_buffer(struct yy_buffer_state *)" (?yy_delete_buffer@OBJFormatScanner_yyFlexLexer@@UAEXPAUyy_buffer_state@@@Z) E:\Documents\WCLDriver\libSAR\libWCLVS.lib(OBJParser.obj) libSAR
    Error 29 error LNK2001: unresolved external symbol "public: virtual void
    thiscall OBJFormatScanner_yyFlexLexer::yyrestart(class std::basic_istream<char,struct std::char_traits<char=""> >
    )" (?yyrestart@OBJFormatScanner_yyFlexLexer@@UAEXPAV?$basic_istream@DU?$char_traits@D@std@@@std@@@Z) E:\Documents\WCLDriver\libSAR\libWCLVS.lib(OBJParser.obj) libSAR
    Error 30 error LNK2001: unresolved external symbol "public: virtual void thiscall OBJFormatScanner_yyFlexLexer::switch_streams(class std::basic_istream<char,struct std::char_traits<char=""> > ,class std::basic_ostream<char,struct std::char_traits<char=""> > )" (?switch_streams@OBJFormatScanner_yyFlexLexer@@UAEXPAV?$basic_istream@DU?$char_traits@D@std@@@std@@PAV?$basic_ostream@DU?$char_traits@D@std@@@3@@Z) E:\Documents\WCLDriver\libSAR\libWCLVS.lib(OBJParser.obj) libSAR
    Error 31 error LNK2001: unresolved external symbol "public: virtual int
    thiscall OBJFormatScanner_yyFlexLexer::yywrap(void)" (?yywrap@OBJFormatScanner_yyFlexLexer@@UAEHXZ) E:\Documents\WCLDriver\libSAR\libWCLVS.lib(OBJParser.obj) libSAR
    Error 32 error LNK2001: unresolved external symbol "protected: virtual int thiscall OBJFormatScanner_yyFlexLexer::LexerInput(char *,int)" (?LexerInput@OBJFormatScanner_yyFlexLexer@@MAEHPADH@Z) E:\Documents\WCLDriver\libSAR\libWCLVS.lib(OBJParser.obj) libSAR
    Error 33 error LNK2001: unresolved external symbol "protected: virtual void
    thiscall OBJFormatScanner_yyFlexLexer::LexerOutput(char const ,int)" (?LexerOutput@OBJFormatScanner_yyFlexLexer@@MAEXPBDH@Z) E:\Documents\WCLDriver\libSAR\libWCLVS.lib(OBJParser.obj) libSAR
    Error 34 error LNK2001: unresolved external symbol "private: virtual int thiscall wcl::OBJFormatScanner::yylex(void)" (?yylex@OBJFormatScanner@wcl@@EAEHXZ) E:\Documents\WCLDriver\libSAR\libWCLVS.lib(OBJParser.obj) libSAR
    Error 35 error LNK2001: unresolved external symbol "private: virtual void
    thiscall wcl::OBJFormatScanner::LexerError(char const
    )" (?LexerError@OBJFormatScanner@wcl@@EAEXPBD@Z) E:\Documents\WCLDriver\libSAR\libWCLVS.lib(OBJParser.obj) libSAR

    Both the OBJFormatScanner and OBJParser classes are in the original lib A that compiles fine until inclusion in lib B. Any suggestions what's causing it? Am I right in saying it is the yyclass option that's the root cause?

    Edit: I'm not sure if it's relevant, but I forgot to add that my OBJFormatScanner class is the class extending the custom yyFlexLexer as follows:

    include <FlexLexer.h>

    ...
    class OBJFormatScanner: public OBJFormatScanner_yyFlexLexer

     

    Last edit: walshy002000 2014-12-04
    • Alex Zhondin

      Alex Zhondin - 2014-12-05

      Hi James,
      Actually I'm not familiar with C++ scanners.

      I agree it seems like your library A doesn't contain implementation code for these functions:

      • OBJFormatScanner_yyFlexLexer::OBJFormatScanner_yyFlexLexer
      • OBJFormatScanner_yyFlexLexer::~OBJFormatScanner_yyFlexLexer
      • OBJFormatScanner_yyFlexLexer::yy_switch_to_buffer
      • and so on

      Can you check if these functions are implemented in OBJFormatScanner.flex.cpp file and this file actually included in your A library?

      I've issued some problems with "Additional Options" section in properties dialog: options from this sections is not reflected in flex command. I'm investigating the problem now. I don't know if it's my local problem or not.

      Please try to invoke win_flex.exe command with all needed options from console (cmd.exe) and check output and generated cpp file.

      Best wishes,
      Alex

       
  • Alex Zhondin

    Alex Zhondin - 2014-12-06

    I've updated winflexbison package.
    Now custom build rules should work correctly.

     
  • walshy002000

    walshy002000 - 2014-12-18

    Hi Alex,

    Sorry for the delayed response. I'm not getting any OBJFormatScanner.flex.cpp file being generated at all (but I do get OBJFormatGrammar.tab.cpp and OBJFormatGrammar.tab.h) - either through VS or by running:

    win_flex.exe --outfile="OBJFormatScanner.flex.cpp" --yyclass="OBJFormatScanner" --wincompat "OBJFormatScanner.l"

    --yyclass="OBJFormatScanner" can't be the last argument, otherwise flex tries to open it as the input, so I put it before the --wincompat argument.

    Any suggestions?

     
    • Alex Zhondin

      Alex Zhondin - 2014-12-19

      Hi James,

      I think we should continue this topic via e-mail.
      Please send me your OBJFormatScanner.l flex file to lexxmark.dev@gmail.com and I will try to help you.

      Regards,
      Alex

       

Log in to post a comment.