axilmar / parserlib

A c++ recursive-descent generic parsing library that supports left recursion.
Apache License 2.0
92 stars 19 forks source link

build error on code like: typedef Char Char; #16

Open asmwarrior opened 1 week ago

asmwarrior commented 1 week ago

I got a lot of error, see below when using GCC compiler:

-------------- Build: Debug in test_parser_lib (compiler: GNU GCC Compiler)---------------

[ 50.0%] g++.exe -Wall -fexceptions -g -Iinclude -c main.cpp -o obj\Debug\main.o
[100.0%] g++.exe  -o bin\Debug\test_parser_lib.exe obj\Debug\main.o   
In file included from include/parserlib/core.hpp:5,
                 from include/parserlib.hpp:5,
                 from main.cpp:2:
include/parserlib/core/TerminalParser.hpp:22:22: error: declaration of 'typedef Char parserlib::core::TerminalParser<Value>::Char' shadows template parameter
   22 |         typedef Char Char;
      |                      ^~~~
include/parserlib/core/TerminalParser.hpp:16:15: note: template parameter 'Char' declared here
   16 |     template <class Char>
      |               ^~~~~
In file included from include/parserlib/core/ParseContext.hpp:11,
                 from include/parserlib/core/Rule.hpp:7,
                 from include/parserlib/core.hpp:10:
include/parserlib/core/ParseState.hpp:18:24: error: declaration of 'typedef Source parserlib::core::ParseState<Source>::Source' shadows template parameter
   18 |         typedef Source Source;
      |                        ^~~~~~
include/parserlib/core/ParseState.hpp:12:15: note: template parameter 'Source' declared here
   12 |     template <class Source>
      |               ^~~~~
In file included from include/parserlib/core/ParseContext.hpp:12:
include/parserlib/core/ParseError.hpp:24:24: error: declaration of 'typedef Source parserlib::core::ParseError<Source>::Source' shadows template parameter
   24 |         typedef Source Source;
      |                        ^~~~~~
include/parserlib/core/ParseError.hpp:18:15: note: template parameter 'Source' declared here
   18 |     template <class Source>
      |               ^~~~~
In file included from include/parserlib/core/ParseContext.hpp:14:
include/parserlib/core/SourceString.hpp:79:24: error: declaration of 'typedef Source parserlib::core::SourceString<Source, CaseTraits, NewlineTraits>::Source' shadows template parameter
   79 |         typedef Source Source;
      |                        ^~~~~~
include/parserlib/core/SourceString.hpp:74:15: note: template parameter 'Source' declared here
   74 |     template <class Source = std::string, class CaseTraits = CaseSensitiveTraits, class NewlineTraits = DefaultNewlineTraits> class SourceString {
      |               ^~~~~
include/parserlib/core/SourceString.hpp:84:28: error: declaration of 'typedef CaseTraits parserlib::core::SourceString<Source, CaseTraits, NewlineTraits>::CaseTraits' shadows template parameter
   84 |         typedef CaseTraits CaseTraits;
      |                            ^~~~~~~~~~
include/parserlib/core/SourceString.hpp:74:43: note: template parameter 'CaseTraits' declared here
   74 |     template <class Source = std::string, class CaseTraits = CaseSensitiveTraits, class NewlineTraits = DefaultNewlineTraits> class SourceString {
      |                                           ^~~~~
include/parserlib/core/SourceString.hpp:89:31: error: declaration of 'typedef NewlineTraits parserlib::core::SourceString<Source, CaseTraits, NewlineTraits>::NewlineTraits' shadows template parameter
   89 |         typedef NewlineTraits NewlineTraits;
      |                               ^~~~~~~~~~~~~
include/parserlib/core/SourceString.hpp:74:83: note: template parameter 'NewlineTraits' declared here
   74 |     template <class Source = std::string, class CaseTraits = CaseSensitiveTraits, class NewlineTraits = DefaultNewlineTraits> class SourceString {
      |                                                                                   ^~~~~
In file included from include/parserlib/core/ParseContext.hpp:16:
include/parserlib/core/Match.hpp:37:25: error: declaration of 'typedef MatchID parserlib::core::Match<MatchID, Source>::MatchID' shadows template parameter
   37 |         typedef MatchID MatchID;
      |                         ^~~~~~~
include/parserlib/core/Match.hpp:31:15: note: template parameter 'MatchID' declared here
   31 |     template <class MatchID, class Source>
      |               ^~~~~
include/parserlib/core/Match.hpp:42:24: error: declaration of 'typedef Source parserlib::core::Match<MatchID, Source>::Source' shadows template parameter
   42 |         typedef Source Source;
      |                        ^~~~~~
include/parserlib/core/Match.hpp:31:30: note: template parameter 'Source' declared here
   31 |     template <class MatchID, class Source>
      |                              ^~~~~
include/parserlib/core/ParseContext.hpp:40:25: error: declaration of 'typedef MatchID parserlib::core::ParseContext<MatchID, Source>::MatchID' shadows template parameter
   40 |         typedef MatchID MatchID;
      |                         ^~~~~~~
include/parserlib/core/ParseContext.hpp:34:15: note: template parameter 'MatchID' declared here
   34 |     template <class MatchID = int, class Source = SourceString<>>
      |               ^~~~~
include/parserlib/core/ParseContext.hpp:45:24: error: declaration of 'typedef Source parserlib::core::ParseContext<MatchID, Source>::Source' shadows template parameter
   45 |         typedef Source Source;
      |                        ^~~~~~
include/parserlib/core/ParseContext.hpp:34:36: note: template parameter 'Source' declared here
   34 |     template <class MatchID = int, class Source = SourceString<>>
      |                                    ^~~~~
include/parserlib/core/Rule.hpp:40:30: error: declaration of 'typedef ParseContext parserlib::core::Rule<ParseContext>::ParseContext' shadows template parameter
   40 |         typedef ParseContext ParseContext;
      |                              ^~~~~~~~~~~~
include/parserlib/core/Rule.hpp:34:15: note: template parameter 'ParseContext' declared here
   34 |     template <class ParseContext = ParseContext<>>
      |               ^~~~~
include/parserlib/core/Rule.hpp:250:19: error: declaration of template parameter 'ParseContext' shadows template parameter
  250 |         template <class ParseContext>
      |                   ^~~~~
include/parserlib/core/Rule.hpp:34:15: note: template parameter 'ParseContext' declared here
   34 |     template <class ParseContext = ParseContext<>>
      |               ^~~~~
include/parserlib/core/Rule.hpp:265:19: error: declaration of template parameter 'ParseContext' shadows template parameter
  265 |         template <class ParseContext>
      |                   ^~~~~
include/parserlib/core/Rule.hpp:34:15: note: template parameter 'ParseContext' declared here
   34 |     template <class ParseContext = ParseContext<>>
      |               ^~~~~
In file included from include/parserlib/cfe/AST.hpp:11,
                 from include/parserlib/cfe/parse.hpp:8,
                 from include/parserlib/cfe/CFE.hpp:6,
                 from include/parserlib/cfe/EBNF.hpp:10,
                 from include/parserlib/cfe.hpp:5,
                 from include/parserlib.hpp:6:
include/parserlib/cfe/Token.hpp:28:25: error: declaration of 'typedef TokenID parserlib::cfe::Token<TokenID, Source>::TokenID' shadows template parameter
   28 |         typedef TokenID TokenID;
      |                         ^~~~~~~
include/parserlib/cfe/Token.hpp:23:15: note: template parameter 'TokenID' declared here
   23 |     template <class TokenID = int, class Source = core::SourceString<>> class Token {
      |               ^~~~~
include/parserlib/cfe/Token.hpp:33:24: error: declaration of 'typedef Source parserlib::cfe::Token<TokenID, Source>::Source' shadows template parameter
   33 |         typedef Source Source;
      |                        ^~~~~~
include/parserlib/cfe/Token.hpp:23:36: note: template parameter 'Source' declared here
   23 |     template <class TokenID = int, class Source = core::SourceString<>> class Token {
      |                                    ^~~~~
include/parserlib/cfe/AST.hpp:30:23: error: declaration of 'typedef ASTID parserlib::cfe::AST<ASTID, Source>::ASTID' shadows template parameter
   30 |         typedef ASTID ASTID;
      |                       ^~~~~
include/parserlib/cfe/AST.hpp:24:15: note: template parameter 'ASTID' declared here
   24 |     template <class ASTID = int, class Source = TokenContainer<>>
      |               ^~~~~
include/parserlib/cfe/AST.hpp:35:24: error: declaration of 'typedef Source parserlib::cfe::AST<ASTID, Source>::Source' shadows template parameter
   35 |         typedef Source Source;
      |                        ^~~~~~
include/parserlib/cfe/AST.hpp:24:34: note: template parameter 'Source' declared here
   24 |     template <class ASTID = int, class Source = TokenContainer<>>
      |                                  ^~~~~
include/parserlib/cfe/CFE.hpp:31:25: error: declaration of 'typedef TokenID parserlib::cfe::CFE<TokenID, ASTID, Source>::TokenID' shadows template parameter
   31 |         typedef TokenID TokenID;
      |                         ^~~~~~~
include/parserlib/cfe/CFE.hpp:25:15: note: template parameter 'TokenID' declared here
   25 |     template <class TokenID = int, class ASTID = int, class Source = core::SourceString<>>
      |               ^~~~~
include/parserlib/cfe/CFE.hpp:36:23: error: declaration of 'typedef ASTID parserlib::cfe::CFE<TokenID, ASTID, Source>::ASTID' shadows template parameter
   36 |         typedef ASTID ASTID;
      |                       ^~~~~
include/parserlib/cfe/CFE.hpp:25:36: note: template parameter 'ASTID' declared here
   25 |     template <class TokenID = int, class ASTID = int, class Source = core::SourceString<>>
      |                                    ^~~~~
include/parserlib/cfe/CFE.hpp:41:24: error: declaration of 'typedef Source parserlib::cfe::CFE<TokenID, ASTID, Source>::Source' shadows template parameter
   41 |         typedef Source Source;
      |                        ^~~~~~
include/parserlib/cfe/CFE.hpp:25:55: note: template parameter 'Source' declared here
   25 |     template <class TokenID = int, class ASTID = int, class Source = core::SourceString<>>
      |                                                       ^~~~~
include/parserlib/cfe/EBNF.hpp:505:26: error: expected nested-name-specifier before 'Source'
  505 |         typedef typename Source Source;
      |                          ^~~~~~
include/parserlib/cfe/EBNF.hpp:505:26: error: expected ';' at end of member declaration
  505 |         typedef typename Source Source;
      |                          ^~~~~~
      |                                ;
include/parserlib/cfe/EBNF.hpp:505:26: error: declaration of 'typedef int parserlib::cfe::EBNF<Source>::Source' shadows template parameter
include/parserlib/cfe/EBNF.hpp:203:15: note: template parameter 'Source' declared here
  203 |     template <class Source = core::SourceString<>> class EBNF {
      |               ^~~~~
include/parserlib/cfe/EBNF.hpp:505:33: error: declaration does not declare anything [-fpermissive]
  505 |         typedef typename Source Source;
      |                                 ^~~~~~
include/parserlib/cfe/EBNF.hpp: In static member function 'static bool parserlib::cfe::EBNF<Source>::createCFE(const ASTContainerPtr&, const std::string&, const std::string&)':
include/parserlib/cfe/EBNF.hpp:570:9: warning: no return statement in function returning non-void [-Wreturn-type]
  570 |         }
      |         ^
main.cpp: At global scope:
main.cpp:62:27: error: 'Source' in 'CalculatorCFE::CFE' {aka 'class parserlib::cfe::CFE<CalculatorCFE::TokenId, CalculatorCFE::ASTId>'} does not name a type
   62 |     typedef typename CFE::Source Source;
      |                           ^~~~~~
main.cpp: In member function 'std::tuple<bool, std::unique_ptr<std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> > > >, std::default_delete<std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> > > > > >, std::unique_ptr<std::vector<std::shared_ptr<parserlib::cfe::AST<CalculatorCFE::ASTId, std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> > > > > >, std::allocator<std::shared_ptr<parserlib::cfe::AST<CalculatorCFE::ASTId, std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> > > > > > > >, std::default_delete<std::vector<std::shared_ptr<parserlib::cfe::AST<CalculatorCFE::ASTId, std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> > > > > >, std::allocator<std::shared_ptr<parserlib::cfe::AST<CalculatorCFE::ASTId, std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> > > > > > > > > >, std::unique_ptr<std::vector<parserlib::core::ParseError<parserlib::core::SourceString<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> >, std::allocator<parserlib::core::ParseError<parserlib::core::SourceString<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> > > >, std::default_delete<std::vector<parserlib::core::ParseError<parserlib::core::SourceString<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> >, std::allocator<parserlib::core::ParseError<parserlib::core::SourceString<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> > > > > > > CalculatorCFE::parse(Source&)':
main.cpp:109:26: error: no matching function for call to 'parserlib::cfe::CFE<CalculatorCFE::TokenId, CalculatorCFE::ASTId>::parse(CalculatorCFE::Source&, CalculatorCFE::TokenizerRule&, CalculatorCFE::ParserRule&)'
  109 |         return CFE::parse(input, m_tokenizerGrammar, m_parserGrammar);
      |                ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/parserlib/cfe/CFE.hpp:123:9: note: candidate: 'template<class TokenGrammar, class ASTGrammar, class CreateAstFunc> static std::tuple<bool, std::unique_ptr<std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > >, std::default_delete<std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > > > >, std::unique_ptr<std::vector<std::shared_ptr<parserlib::cfe::AST<ASTID, std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > > > >, std::allocator<std::shared_ptr<parserlib::cfe::AST<ASTID, std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > > > > > >, std::default_delete<std::vector<std::shared_ptr<parserlib::cfe::AST<ASTID, std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > > > >, std::allocator<std::shared_ptr<parserlib::cfe::AST<ASTID, std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > > > > > > > >, std::unique_ptr<std::vector<parserlib::core::ParseError<Source>, std::allocator<parserlib::core::ParseError<Source> > >, std::default_delete<std::vector<parserlib::core::ParseError<Source>, std::allocator<parserlib::core::ParseError<Source> > > > > > parserlib::cfe::CFE<TokenID, ASTID, Source>::parse(Source&, TokenGrammar&&, ASTGrammar&&, CreateAstFunc&&) [with ASTGrammar = TokenGrammar; CreateAstFunc = ASTGrammar; TokenID = CalculatorCFE::TokenId; ASTID = CalculatorCFE::ASTId; Source = parserlib::core::SourceString<>]'
  123 |         parse(Source& input, TokenGrammar&& tokenGrammar, ASTGrammar&& astGrammar, CreateAstFunc&& createAST) {
      |         ^~~~~
include/parserlib/cfe/CFE.hpp:123:9: note:   template argument deduction/substitution failed:
main.cpp:109:26: note:   candidate expects 4 arguments, 3 provided
  109 |         return CFE::parse(input, m_tokenizerGrammar, m_parserGrammar);
      |                ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/parserlib/cfe/CFE.hpp:156:13: note: candidate: 'template<class TokenGrammar, class ASTGrammar> static std::tuple<bool, std::unique_ptr<std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > >, std::default_delete<std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > > > >, std::unique_ptr<std::vector<std::shared_ptr<parserlib::cfe::AST<ASTID, std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > > > >, std::allocator<std::shared_ptr<parserlib::cfe::AST<ASTID, std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > > > > > >, std::default_delete<std::vector<std::shared_ptr<parserlib::cfe::AST<ASTID, std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > > > >, std::allocator<std::shared_ptr<parserlib::cfe::AST<ASTID, std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > > > > > > > >, std::unique_ptr<std::vector<parserlib::core::ParseError<Source>, std::allocator<parserlib::core::ParseError<Source> > >, std::default_delete<std::vector<parserlib::core::ParseError<Source>, std::allocator<parserlib::core::ParseError<Source> > > > > > parserlib::cfe::CFE<TokenID, ASTID, Source>::parse(Source&, TokenGrammar&&, ASTGrammar&&) [with ASTGrammar = TokenGrammar; TokenID = CalculatorCFE::TokenId; ASTID = CalculatorCFE::ASTId; Source = parserlib::core::SourceString<>]'
  156 |             parse(Source& input, TokenGrammar&& tokenGrammar, ASTGrammar&& astGrammar)
      |             ^~~~~
include/parserlib/cfe/CFE.hpp:156:13: note:   template argument deduction/substitution failed:
main.cpp:109:27: note:   cannot convert 'input' (type 'CalculatorCFE::Source' {aka 'int'}) to type 'parserlib::core::SourceString<>&'
  109 |         return CFE::parse(input, m_tokenizerGrammar, m_parserGrammar);
      |                           ^~~~~
include/parserlib/cfe/AST.hpp: In instantiation of 'class parserlib::cfe::AST<CalculatorCFE::ASTId, std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> > > > >':
main.cpp:113:20:   required from here
include/parserlib/cfe/AST.hpp:65:40: error: no type named 'Source' in 'parserlib::cfe::AST<CalculatorCFE::ASTId, std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> > > > >::Token' {aka 'class parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> >'}
   65 |         typedef typename Token::Source TokenSource;
      |                                        ^~~~~~~~~~~
include/parserlib/cfe/AST.hpp:70:74: error: no type named 'Source' in 'std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> > > >::value_type' {aka 'class parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> >'}
   70 |         typedef std::basic_string_view<typename TokenSource::value_type> StringView;
      |                                                                          ^~~~~~~~~~
include/parserlib/cfe/AST.hpp:205:61: error: no type named 'Source' in 'std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> > > >::value_type' {aka 'class parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> >'}
  205 |         std::basic_string<typename TokenSource::value_type> toString(size_t maxSourceCharsPerLine = 32) const {
      |                                                             ^~~~~~~~
main.cpp: In static member function 'static double CalculatorCFE::evaluate(const ASTPtr&)':
main.cpp:116:32: error: 'using std::__shared_ptr_access<parserlib::cfe::AST<CalculatorCFE::ASTId, std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> > > > >, __gnu_cxx::_S_atomic, false, false>::element_type = class parserlib::cfe::AST<CalculatorCFE::ASTId, std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> > > > >' {aka 'class parserlib::cfe::AST<CalculatorCFE::ASTId, std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> > > > >'} has no member named 'getSource'; did you mean 'TokenSource'?
  116 |                 stream << ast->getSource();
      |                                ^~~~~~~~~
      |                                TokenSource
Process terminated with status 1 (0 minute(s), 1 second(s))
30 error(s), 3 warning(s) (0 minute(s), 1 second(s))

I just copied the CFE example code to my "main.cpp".

Any ideas?

I guess you are using MSVC compiler, which is more permissive?

axilmar commented 1 week ago

My apologies for the errors, I fixed them, thanks to Code::Blocks.

I never thought that in 2024, Microsoft would continue the 'embrace & extend' strategy.

On Fri, Oct 11, 2024 at 11:38 AM ollydbg @.***> wrote:

I got a lot of error, see below when using GCC compiler:

-------------- Build: Debug in test_parser_lib (compiler: GNU GCC Compiler)---------------

[ 50.0%] g++.exe -Wall -fexceptions -g -Iinclude -c main.cpp -o obj\Debug\main.o [100.0%] g++.exe -o bin\Debug\test_parser_lib.exe obj\Debug\main.o In file included from include/parserlib/core.hpp:5, from include/parserlib.hpp:5, from main.cpp:2: include/parserlib/core/TerminalParser.hpp:22:22: error: declaration of 'typedef Char parserlib::core::TerminalParser::Char' shadows template parameter 22 | typedef Char Char; | ^~~~ include/parserlib/core/TerminalParser.hpp:16:15: note: template parameter 'Char' declared here 16 | template | ^~~~~ In file included from include/parserlib/core/ParseContext.hpp:11, from include/parserlib/core/Rule.hpp:7, from include/parserlib/core.hpp:10: include/parserlib/core/ParseState.hpp:18:24: error: declaration of 'typedef Source parserlib::core::ParseState::Source' shadows template parameter 18 | typedef Source Source; | ^~ include/parserlib/core/ParseState.hpp:12:15: note: template parameter 'Source' declared here 12 | template | ^~~~~ In file included from include/parserlib/core/ParseContext.hpp:12: include/parserlib/core/ParseError.hpp:24:24: error: declaration of 'typedef Source parserlib::core::ParseError::Source' shadows template parameter 24 | typedef Source Source; | ^~ include/parserlib/core/ParseError.hpp:18:15: note: template parameter 'Source' declared here 18 | template | ^~~~~ In file included from include/parserlib/core/ParseContext.hpp:14: include/parserlib/core/SourceString.hpp:79:24: error: declaration of 'typedef Source parserlib::core::SourceString<Source, CaseTraits, NewlineTraits>::Source' shadows template parameter 79 | typedef Source Source; | ^~ include/parserlib/core/SourceString.hpp:74:15: note: template parameter 'Source' declared here 74 | template class SourceString { | ^~~~~ include/parserlib/core/SourceString.hpp:84:28: error: declaration of 'typedef CaseTraits parserlib::core::SourceString<Source, CaseTraits, NewlineTraits>::CaseTraits' shadows template parameter 84 | typedef CaseTraits CaseTraits; | ^~~~~~ include/parserlib/core/SourceString.hpp:74:43: note: template parameter 'CaseTraits' declared here 74 | template class SourceString { | ^~~~~ include/parserlib/core/SourceString.hpp:89:31: error: declaration of 'typedef NewlineTraits parserlib::core::SourceString<Source, CaseTraits, NewlineTraits>::NewlineTraits' shadows template parameter 89 | typedef NewlineTraits NewlineTraits; | ^~~~~ include/parserlib/core/SourceString.hpp:74:83: note: template parameter 'NewlineTraits' declared here 74 | template class SourceString { | ^~~~~ In file included from include/parserlib/core/ParseContext.hpp:16: include/parserlib/core/Match.hpp:37:25: error: declaration of 'typedef MatchID parserlib::core::Match<MatchID, Source>::MatchID' shadows template parameter 37 | typedef MatchID MatchID; | ^~~ include/parserlib/core/Match.hpp:31:15: note: template parameter 'MatchID' declared here 31 | template <class MatchID, class Source> | ^~~~~ include/parserlib/core/Match.hpp:42:24: error: declaration of 'typedef Source parserlib::core::Match<MatchID, Source>::Source' shadows template parameter 42 | typedef Source Source; | ^~ include/parserlib/core/Match.hpp:31:30: note: template parameter 'Source' declared here 31 | template <class MatchID, class Source> | ^~~~~ include/parserlib/core/ParseContext.hpp:40:25: error: declaration of 'typedef MatchID parserlib::core::ParseContext<MatchID, Source>::MatchID' shadows template parameter 40 | typedef MatchID MatchID; | ^~~ include/parserlib/core/ParseContext.hpp:34:15: note: template parameter 'MatchID' declared here 34 | template <class MatchID = int, class Source = SourceString<>> | ^~~~~ include/parserlib/core/ParseContext.hpp:45:24: error: declaration of 'typedef Source parserlib::core::ParseContext<MatchID, Source>::Source' shadows template parameter 45 | typedef Source Source; | ^~ include/parserlib/core/ParseContext.hpp:34:36: note: template parameter 'Source' declared here 34 | template <class MatchID = int, class Source = SourceString<>> | ^~~~~ include/parserlib/core/Rule.hpp:40:30: error: declaration of 'typedef ParseContext parserlib::core::Rule::ParseContext' shadows template parameter 40 | typedef ParseContext ParseContext; | ^~~~ include/parserlib/core/Rule.hpp:34:15: note: template parameter 'ParseContext' declared here 34 | template <class ParseContext = ParseContext<>> | ^~~~~ include/parserlib/core/Rule.hpp:250:19: error: declaration of template parameter 'ParseContext' shadows template parameter 250 | template | ^~~~~ include/parserlib/core/Rule.hpp:34:15: note: template parameter 'ParseContext' declared here 34 | template <class ParseContext = ParseContext<>> | ^~~~~ include/parserlib/core/Rule.hpp:265:19: error: declaration of template parameter 'ParseContext' shadows template parameter 265 | template | ^~~~~ include/parserlib/core/Rule.hpp:34:15: note: template parameter 'ParseContext' declared here 34 | template <class ParseContext = ParseContext<>> | ^~~~~ In file included from include/parserlib/cfe/AST.hpp:11, from include/parserlib/cfe/parse.hpp:8, from include/parserlib/cfe/CFE.hpp:6, from include/parserlib/cfe/EBNF.hpp:10, from include/parserlib/cfe.hpp:5, from include/parserlib.hpp:6: include/parserlib/cfe/Token.hpp:28:25: error: declaration of 'typedef TokenID parserlib::cfe::Token<TokenID, Source>::TokenID' shadows template parameter 28 | typedef TokenID TokenID; | ^~~ include/parserlib/cfe/Token.hpp:23:15: note: template parameter 'TokenID' declared here 23 | template <class TokenID = int, class Source = core::SourceString<>> class Token { | ^~~~~ include/parserlib/cfe/Token.hpp:33:24: error: declaration of 'typedef Source parserlib::cfe::Token<TokenID, Source>::Source' shadows template parameter 33 | typedef Source Source; | ^~ include/parserlib/cfe/Token.hpp:23:36: note: template parameter 'Source' declared here 23 | template <class TokenID = int, class Source = core::SourceString<>> class Token { | ^~~~~ include/parserlib/cfe/AST.hpp:30:23: error: declaration of 'typedef ASTID parserlib::cfe::AST<ASTID, Source>::ASTID' shadows template parameter 30 | typedef ASTID ASTID; | ^~~~~ include/parserlib/cfe/AST.hpp:24:15: note: template parameter 'ASTID' declared here 24 | template <class ASTID = int, class Source = TokenContainer<>> | ^~~~~ include/parserlib/cfe/AST.hpp:35:24: error: declaration of 'typedef Source parserlib::cfe::AST<ASTID, Source>::Source' shadows template parameter 35 | typedef Source Source; | ^~ include/parserlib/cfe/AST.hpp:24:34: note: template parameter 'Source' declared here 24 | template <class ASTID = int, class Source = TokenContainer<>> | ^~~~~ include/parserlib/cfe/CFE.hpp:31:25: error: declaration of 'typedef TokenID parserlib::cfe::CFE<TokenID, ASTID, Source>::TokenID' shadows template parameter 31 | typedef TokenID TokenID; | ^~~ include/parserlib/cfe/CFE.hpp:25:15: note: template parameter 'TokenID' declared here 25 | template <class TokenID = int, class ASTID = int, class Source = core::SourceString<>> | ^~~~~ include/parserlib/cfe/CFE.hpp:36:23: error: declaration of 'typedef ASTID parserlib::cfe::CFE<TokenID, ASTID, Source>::ASTID' shadows template parameter 36 | typedef ASTID ASTID; | ^~~~~ include/parserlib/cfe/CFE.hpp:25:36: note: template parameter 'ASTID' declared here 25 | template <class TokenID = int, class ASTID = int, class Source = core::SourceString<>> | ^~~~~ include/parserlib/cfe/CFE.hpp:41:24: error: declaration of 'typedef Source parserlib::cfe::CFE<TokenID, ASTID, Source>::Source' shadows template parameter 41 | typedef Source Source; | ^~ include/parserlib/cfe/CFE.hpp:25:55: note: template parameter 'Source' declared here 25 | template <class TokenID = int, class ASTID = int, class Source = core::SourceString<>> | ^~~~~ include/parserlib/cfe/EBNF.hpp:505:26: error: expected nested-name-specifier before 'Source' 505 | typedef typename Source Source; | ^~ include/parserlib/cfe/EBNF.hpp:505:26: error: expected ';' at end of member declaration 505 | typedef typename Source Source; | ^~ | ; include/parserlib/cfe/EBNF.hpp:505:26: error: declaration of 'typedef int parserlib::cfe::EBNF::Source' shadows template parameter include/parserlib/cfe/EBNF.hpp:203:15: note: template parameter 'Source' declared here 203 | template <class Source = core::SourceString<>> class EBNF { | ^~~~~ include/parserlib/cfe/EBNF.hpp:505:33: error: declaration does not declare anything [-fpermissive] 505 | typedef typename Source Source; | ^~ include/parserlib/cfe/EBNF.hpp: In static member function 'static bool parserlib::cfe::EBNF::createCFE(const ASTContainerPtr&, const std::string&, const std::string&)': include/parserlib/cfe/EBNF.hpp:570:9: warning: no return statement in function returning non-void [-Wreturn-type] 570 | } | ^ main.cpp: At global scope: main.cpp:62:27: error: 'Source' in 'CalculatorCFE::CFE' {aka 'class parserlib::cfe::CFE<CalculatorCFE::TokenId, CalculatorCFE::ASTId>'} does not name a type 62 | typedef typename CFE::Source Source; | ^~ main.cpp: In member function 'std::tuple<bool, std::unique_ptr<std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::cxx11::basic_string<char, std::char_traits, std::allocator >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::cxx11::basic_string<char, std::char_traits, std::allocator >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> > > >, std::default_delete<std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::cxx11::basic_string<char, std::char_traits, std::allocator >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::cxx11::basic_string<char, std::char_traits, std::allocator >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> > > > > >, std::unique_ptr<std::vector<std::shared_ptr<parserlib::cfe::AST<CalculatorCFE::ASTId, std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::cxx11::basic_string<char, std::char_traits, std::allocator >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::cxx11::basic_string<char, std::char_traits, std::allocator >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> > > > > >, std::allocator<std::shared_ptr<parserlib::cfe::AST<CalculatorCFE::ASTId, std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::cxx11::basic_string<char, std::char_traits, std::allocator >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::cxx11::basic_string<char, std::char_traits, std::allocator >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> > > > > > > >, std::default_delete<std::vector<std::shared_ptr<parserlib::cfe::AST<CalculatorCFE::ASTId, std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::cxx11::basic_string<char, std::char_traits, std::allocator >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::cxx11::basic_string<char, std::char_traits, std::allocator >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> > > > > >, std::allocator<std::shared_ptr<parserlib::cfe::AST<CalculatorCFE::ASTId, std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::cxx11::basic_string<char, std::char_traits, std::allocator >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<std::cxx11::basic_string<char, std::char_traits, std::allocator >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> > > > > > > > > >, std::unique_ptr<std::vector<parserlib::core::ParseError<parserlib::core::SourceString<std::cxx11::basic_string<char, std::char_traits, std::allocator >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> >, std::allocator<parserlib::core::ParseError<parserlib::core::SourceString<std::cxx11::basic_string<char, std::char_traits, std::allocator >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> > > >, std::default_delete<std::vector<parserlib::core::ParseError<parserlib::core::SourceString<std::cxx11::basic_string<char, std::char_traits, std::allocator >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> >, std::allocator<parserlib::core::ParseError<parserlib::core::SourceString<std::cxx11::basic_string<char, std::char_traits, std::allocator >, parserlib::core::CaseSensitiveTraits, parserlib::core::DefaultNewlineTraits> > > > > > > CalculatorCFE::parse(Source&)': main.cpp:109:26: error: no matching function for call to 'parserlib::cfe::CFE<CalculatorCFE::TokenId, CalculatorCFE::ASTId>::parse(CalculatorCFE::Source&, CalculatorCFE::TokenizerRule&, CalculatorCFE::ParserRule&)' 109 | return CFE::parse(input, m_tokenizerGrammar, m_parserGrammar); | ~~^~~~~~~~~~~~ include/parserlib/cfe/CFE.hpp:123:9: note: candidate: 'template<class TokenGrammar, class ASTGrammar, class CreateAstFunc> static std::tuple<bool, std::unique_ptr<std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > >, std::default_delete<std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > > > >, std::unique_ptr<std::vector<std::shared_ptr<parserlib::cfe::AST<ASTID, std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > > > >, std::allocator<std::shared_ptr<parserlib::cfe::AST<ASTID, std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > > > > > >, std::default_delete<std::vector<std::shared_ptr<parserlib::cfe::AST<ASTID, std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > > > >, std::allocator<std::shared_ptr<parserlib::cfe::AST<ASTID, std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > > > > > > > >, std::unique_ptr<std::vector<parserlib::core::ParseError, std::allocator<parserlib::core::ParseError > >, std::default_delete<std::vector<parserlib::core::ParseError, std::allocator<parserlib::core::ParseError > > > > > parserlib::cfe::CFE<TokenID, ASTID, Source>::parse(Source&, TokenGrammar&&, ASTGrammar&&, CreateAstFunc&&) [with ASTGrammar = TokenGrammar; CreateAstFunc = ASTGrammar; TokenID = CalculatorCFE::TokenId; ASTID = CalculatorCFE::ASTId; Source = parserlib::core::SourceString<>]' 123 | parse(Source& input, TokenGrammar&& tokenGrammar, ASTGrammar&& astGrammar, CreateAstFunc&& createAST) { | ^~~~~ include/parserlib/cfe/CFE.hpp:123:9: note: template argument deduction/substitution failed: main.cpp:109:26: note: candidate expects 4 arguments, 3 provided 109 | return CFE::parse(input, m_tokenizerGrammar, m_parserGrammar); | ~~^~~~~~~~~~~~ include/parserlib/cfe/CFE.hpp:156:13: note: candidate: 'template<class TokenGrammar, class ASTGrammar> static std::tuple<bool, std::unique_ptr<std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > >, std::default_delete<std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > > > >, std::unique_ptr<std::vector<std::shared_ptr<parserlib::cfe::AST<ASTID, std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > > > >, std::allocator<std::shared_ptr<parserlib::cfe::AST<ASTID, std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > > > > > >, std::default_delete<std::vector<std::shared_ptr<parserlib::cfe::AST<ASTID, std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > > > >, std::allocator<std::shared_ptr<parserlib::cfe::AST<ASTID, std::vector<parserlib::cfe::Token<TokenID, Source>, std::allocator<parserlib::cfe::Token<TokenID, Source> > > > > > > > >, std::unique_ptr<std::vector<parserlib::core::ParseError, std::allocator<parserlib::core::ParseError > >, std::default_delete<std::vector<parserlib::core::ParseError, std::allocator<parserlib::core::ParseError > > > > > parserlib::cfe::CFE<TokenID, ASTID, Source>::parse(Source&, TokenGrammar&&, ASTGrammar&&) [with ASTGrammar = TokenGrammar; TokenID = CalculatorCFE::TokenId; ASTID = CalculatorCFE::ASTId; Source = parserlib::core::SourceString<>]' 156 | parse(Source& input, TokenGrammar&& tokenGrammar, ASTGrammar&& astGrammar) | ^~~~~ include/parserlib/cfe/CFE.hpp:156:13: note: template argument deduction/substitution failed: main.cpp:109:27: note: cannot convert 'input' (type 'CalculatorCFE::Source' {aka 'int'}) to type 'parserlib::core::SourceString<>&' 109 | return CFE::parse(input, m_tokenizerGrammar, m_parserGrammar); | ^~~~~ include/parserlib/cfe/AST.hpp: In instantiation of 'class parserlib::cfe::AST<CalculatorCFE::ASTId, std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> > > > >': main.cpp:113:20: required from here include/parserlib/cfe/AST.hpp:65:40: error: no type named 'Source' in 'parserlib::cfe::AST<CalculatorCFE::ASTId, std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> > > > >::Token' {aka 'class parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> >'} 65 | typedef typename Token::Source TokenSource; | ^~~ include/parserlib/cfe/AST.hpp:70:74: error: no type named 'Source' in 'std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> > > >::value_type' {aka 'class parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> >'} 70 | typedef std::basic_string_view StringView; | ^~~~~~ include/parserlib/cfe/AST.hpp:205:61: error: no type named 'Source' in 'std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> > > >::value_type' {aka 'class parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> >'} 205 | std::basic_string toString(size_t maxSourceCharsPerLine = 32) const { | ^~~~ main.cpp: In static member function 'static double CalculatorCFE::evaluate(const ASTPtr&)': main.cpp:116:32: error: 'using std::shared_ptr_access<parserlib::cfe::AST<CalculatorCFE::ASTId, std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> > > > >, gnu_cxx::_S_atomic, false, false>::element_type = class parserlib::cfe::AST<CalculatorCFE::ASTId, std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> > > > >' {aka 'class parserlib::cfe::AST<CalculatorCFE::ASTId, std::vector<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> >, std::allocator<parserlib::cfe::Token<CalculatorCFE::TokenId, parserlib::core::SourceString<> > > > >'} has no member named 'getSource'; did you mean 'TokenSource'? 116 | stream << ast->getSource(); | ^~~~~ | TokenSource Process terminated with status 1 (0 minute(s), 1 second(s)) 30 error(s), 3 warning(s) (0 minute(s), 1 second(s))

I just copied the CFE example code to my "main.cpp".

Any ideas?

I guess you are using MSVC compiler, which is more permissive?

— Reply to this email directly, view it on GitHub https://github.com/axilmar/parserlib/issues/16, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAESDFEUDIN35LYJZ2JZQBDZ26FA3AVCNFSM6AAAAABPYODGFOVHI2DSMVQWIX3LMV43ASLTON2WKOZSGU4DANZZGQ4DEMA . You are receiving this because you are subscribed to this thread.Message ID: @.***>

asmwarrior commented 1 week ago

OK, thanks for the fix!


#include "parserlib.hpp"

#include <iostream>

using namespace parserlib;
using namespace core;
using namespace cfe;

class CalculatorCFE {
public:
    enum class TokenId {
        Number,
        AddOp,
        SubOp,
        MulOp,
        DivOp,
        LeftParen,
        RightParen
    };

    enum class ASTId {
        Number,
        AddExpr,
        SubExpr,
        MulExpr,
        DivExpr
    };

    template <class CharT, class CharTraits>
    friend std::basic_ostream<CharT, CharTraits>& operator << (std::basic_ostream<CharT, CharTraits>& stream, ASTId id) {
        switch (id) {
            case ASTId::Number:
                stream << "Number";
                break;
            case ASTId::AddExpr:
                stream << "Add";
                break;
            case ASTId::SubExpr:
                stream << "Sub";
                break;
            case ASTId::MulExpr:
                stream << "Mul";
                break;
            case ASTId::DivExpr:
                stream << "Div";
                break;
        }
        return stream;
    }

    typedef CFE<TokenId, ASTId> CFE;

    typedef typename CFE::TokenizerRule TokenizerRule;

    typedef typename CFE::ParserRule ParserRule;

    typedef typename CFE::ASTPtr ASTPtr;

    typedef typename CFE::ASTContainer ASTContainer;

    typedef typename CFE::ErrorContainer ErrorContainer;

    typedef typename CFE::Source Source;

    typedef typename CFE::TokenContainerPtr TokenContainerPtr;

    typedef typename CFE::ASTContainerPtr ASTContainerPtr;

    typedef typename CFE::ErrorContainerPtr ErrorContainerPtr;

    CalculatorCFE() {
        /**** tokenizer ****/
        auto ws = oneIn('\0', ' ');
        auto digit = oneIn('0', '9');
        auto sign = oneOf('+', '-');
        auto integer = +digit;
        auto number = (-sign >> integer >> -('.' >> integer))->*TokenId::Number;
        auto addOp = term('+')->*TokenId::AddOp;
        auto subOp = term('-')->*TokenId::SubOp;
        auto mulOp = term('*')->*TokenId::MulOp;
        auto divOp = term('/')->*TokenId::DivOp;
        auto leftParen = term('(')->*TokenId::LeftParen;
        auto rightParen = term(')')->*TokenId::RightParen;
        m_tokenizerGrammar = *(ws | number | addOp | subOp | mulOp | divOp | leftParen | rightParen);

        /**** parser ****/

        auto parenExpr = TokenId::LeftParen >> m_add >> TokenId::RightParen;

        auto num = term(TokenId::Number)->*ASTId::Number;

        auto val
            = parenExpr
            | num;

        m_mul
            = (m_mul >> TokenId::MulOp >> val)->*ASTId::MulExpr
            | (m_mul >> TokenId::DivOp >> val)->*ASTId::DivExpr
            | val;

        m_add
            = (m_add >> TokenId::AddOp >> m_mul)->*ASTId::AddExpr
            | (m_add >> TokenId::SubOp >> m_mul)->*ASTId::SubExpr
            | m_mul;

        m_parserGrammar = m_add;
    }

    std::tuple<bool, TokenContainerPtr, ASTContainerPtr, ErrorContainerPtr> parse(Source& input) {
        return CFE::parse(input, m_tokenizerGrammar, m_parserGrammar);
    }

    static double evaluate(const ASTPtr& ast) {
        switch (ast->getID()) {
            case ASTId::Number: {
                std::stringstream stream;
                stream << ast->getSource();
                double r;
                stream >> r;
                return r;
            }

            case ASTId::AddExpr:
                return evaluate(ast->getChildren()[0]) + evaluate(ast->getChildren()[1]);

            case ASTId::SubExpr:
                return evaluate(ast->getChildren()[0]) - evaluate(ast->getChildren()[1]);

            case ASTId::MulExpr:
                return evaluate(ast->getChildren()[0]) * evaluate(ast->getChildren()[1]);

            case ASTId::DivExpr:
                return evaluate(ast->getChildren()[0]) / evaluate(ast->getChildren()[1]);
        }

        throw std::logic_error("invalid CalculatorCFE ASTId.");
    }

private:
    TokenizerRule m_tokenizerGrammar;
    ParserRule m_add;
    ParserRule m_mul;
    ParserRule m_parserGrammar;
};

int main()
{
    CalculatorCFE calc;
    SourceString input = "1.5 + 8.9";
    auto [success, tokens, ast, errors] = calc.parse(input);

    std::cout << CalculatorCFE::evaluate((*ast)[0]) << std::endl;

    return 0;
}

The above code works correctly, and the result is:

10.4

BTW, I see you have comment out a lot of the code in the file tests/parserlib_cfe_tests.cpp, is that by design?

axilmar commented 1 week ago

I commented it out because I hit a wall: the 32-bit MSVC run out of memory and I was trying to fix that.

But I didn't manage to solve the issue, so I installed the 64-bit MSVC, along with Code::Blocks and mingw64, and now I am fully 64-bit and I have put the tests back.

On Sat, Oct 12, 2024 at 6:18 AM ollydbg @.***> wrote:

OK, thanks for the fix!

include "parserlib.hpp"

include

using namespace parserlib; using namespace core; using namespace cfe;

class CalculatorCFE { public: enum class TokenId { Number, AddOp, SubOp, MulOp, DivOp, LeftParen, RightParen };

enum class ASTId {
    Number,
    AddExpr,
    SubExpr,
    MulExpr,
    DivExpr
};

template <class CharT, class CharTraits>
friend std::basic_ostream<CharT, CharTraits>& operator << (std::basic_ostream<CharT, CharTraits>& stream, ASTId id) {
    switch (id) {
        case ASTId::Number:
            stream << "Number";
            break;
        case ASTId::AddExpr:
            stream << "Add";
            break;
        case ASTId::SubExpr:
            stream << "Sub";
            break;
        case ASTId::MulExpr:
            stream << "Mul";
            break;
        case ASTId::DivExpr:
            stream << "Div";
            break;
    }
    return stream;
}

typedef CFE<TokenId, ASTId> CFE;

typedef typename CFE::TokenizerRule TokenizerRule;

typedef typename CFE::ParserRule ParserRule;

typedef typename CFE::ASTPtr ASTPtr;

typedef typename CFE::ASTContainer ASTContainer;

typedef typename CFE::ErrorContainer ErrorContainer;

typedef typename CFE::Source Source;

typedef typename CFE::TokenContainerPtr TokenContainerPtr;

typedef typename CFE::ASTContainerPtr ASTContainerPtr;

typedef typename CFE::ErrorContainerPtr ErrorContainerPtr;

CalculatorCFE() {
    /**** tokenizer ****/
    auto ws = oneIn('\0', ' ');
    auto digit = oneIn('0', '9');
    auto sign = oneOf('+', '-');
    auto integer = +digit;
    auto number = (-sign >> integer >> -('.' >> integer))->*TokenId::Number;
    auto addOp = term('+')->*TokenId::AddOp;
    auto subOp = term('-')->*TokenId::SubOp;
    auto mulOp = term('*')->*TokenId::MulOp;
    auto divOp = term('/')->*TokenId::DivOp;
    auto leftParen = term('(')->*TokenId::LeftParen;
    auto rightParen = term(')')->*TokenId::RightParen;
    m_tokenizerGrammar = *(ws | number | addOp | subOp | mulOp | divOp | leftParen | rightParen);

    /**** parser ****/

    auto parenExpr = TokenId::LeftParen >> m_add >> TokenId::RightParen;

    auto num = term(TokenId::Number)->*ASTId::Number;

    auto val
        = parenExpr
        | num;

    m_mul
        = (m_mul >> TokenId::MulOp >> val)->*ASTId::MulExpr
        | (m_mul >> TokenId::DivOp >> val)->*ASTId::DivExpr
        | val;

    m_add
        = (m_add >> TokenId::AddOp >> m_mul)->*ASTId::AddExpr
        | (m_add >> TokenId::SubOp >> m_mul)->*ASTId::SubExpr
        | m_mul;

    m_parserGrammar = m_add;
}

std::tuple<bool, TokenContainerPtr, ASTContainerPtr, ErrorContainerPtr> parse(Source& input) {
    return CFE::parse(input, m_tokenizerGrammar, m_parserGrammar);
}

static double evaluate(const ASTPtr& ast) {
    switch (ast->getID()) {
        case ASTId::Number: {
            std::stringstream stream;
            stream << ast->getSource();
            double r;
            stream >> r;
            return r;
        }

        case ASTId::AddExpr:
            return evaluate(ast->getChildren()[0]) + evaluate(ast->getChildren()[1]);

        case ASTId::SubExpr:
            return evaluate(ast->getChildren()[0]) - evaluate(ast->getChildren()[1]);

        case ASTId::MulExpr:
            return evaluate(ast->getChildren()[0]) * evaluate(ast->getChildren()[1]);

        case ASTId::DivExpr:
            return evaluate(ast->getChildren()[0]) / evaluate(ast->getChildren()[1]);
    }

    throw std::logic_error("invalid CalculatorCFE ASTId.");
}

private: TokenizerRule m_tokenizerGrammar; ParserRule m_add; ParserRule m_mul; ParserRule m_parserGrammar; };

int main() { CalculatorCFE calc; SourceString input = "1.5 + 8.9"; auto [success, tokens, ast, errors] = calc.parse(input);

std::cout << CalculatorCFE::evaluate((*ast)[0]) << std::endl;

return 0;

}

The above code works correctly, and the result is:

10.4

BTW, I see you have comment out a lot of the code in the file tests/parserlib_cfe_tests.cpp, is that by design?

— Reply to this email directly, view it on GitHub https://github.com/axilmar/parserlib/issues/16#issuecomment-2408328485, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAESDFAFDKHDX2PHFOUN4Y3Z3CIINAVCNFSM6AAAAABPYODGFOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDIMBYGMZDQNBYGU . You are receiving this because you commented.Message ID: @.***>

asmwarrior commented 1 week ago

I commented it out because I hit a wall: the 32-bit MSVC run out of memory and I was trying to fix that. But I didn't manage to solve the issue, so I installed the 64-bit MSVC, along with Code::Blocks and mingw64, and now I am fully 64-bit and I have put the tests back.

Nice work! Thanks. Hope you will solve the 32-bit MSVC issue soon.

asmwarrior commented 4 days ago

I see another issue:

In the testing code of a standalone parser, there are some code like:

struct Token {
    TokenKind kind;
    std::string lexeme;
    int row;
    int column;

    bool operator == (TokenKind tk) const {
        return kind == tk;
    }
};

std::vector<Token> tokens;

And in the library's header file, there are same class Token, see here:

namespace parserlib::cfe {

    /**
     * A token.
     * 
     * It is created from tokenizing an input, and it is fed to a parser to parse a language grammar.
     * 
     * @param TokenID_ id of token.
     * 
     * @param Source_ source for the token.
     */
    template <class TokenID_ = int, class Source_ = core::SourceString<>> class Token {
    public:
        /**
         * Token id type.
         */
        typedef TokenID_ TokenID;

        /**
         * Source type.
         */
        typedef Source_ Source;

        /**
         * Source iterator type.
         */
        typedef typename Source::const_iterator SourceIterator;

        /**
         * Source view type.
         */
        typedef std::basic_string_view<typename Source::value_type> StringView;

        /**
         * Constructor.
         * @param id id of token.
         * @param startPosition start position of the token into the source.
         * @param endPosition end position of the the token into the source.
         */
        Token(const TokenID& id, const SourceIterator& startPosition, const SourceIterator& endPosition)
            : m_id(id)
            , m_startPosition(startPosition)
            , m_endPosition(endPosition)
        {
        }

        /**
         * Returns the token id.
         * @return the token id.
         */
        const TokenID& getID() const {
            return m_id;
        }

        /**
         * Returns the start position.
         * @return the start position.
         */
        const SourceIterator& getStartPosition() const {
            return m_startPosition;
        }

        /**
         * Returns the end position.
         * @return the end position.
         */
        const SourceIterator& getEndPosition() const {
            return m_endPosition;
        }

        /**
         * Returns the source that correponds to this token.
         * @return the source that correponds to this token.
         */
        StringView getSource(size_t maxChars = -1) const {
            const auto* src = &*m_startPosition;
            const size_t size = std::min(maxChars, (size_t)(m_endPosition - m_startPosition));
            return StringView(src, size);
        }

        /**
         * Checks if this token has the given id.
         * @param id id to check.
         * @return true if this token has the given id, false otherwise.
         */
        bool operator == (const TokenID& id) const {
            return m_id == id;
        }

        /**
         * Checks if this token does not have the given id.
         * @param id id to check.
         * @return true if this token does not have the given id, false otherwise.
         */
        bool operator != (const TokenID& id) const {
            return m_id != id;
        }

    private:
        TokenID m_id;
        SourceIterator m_startPosition;
        SourceIterator m_endPosition;
    };

So the names will get conflict if you use the

using namespace parserlib::cfe;
asmwarrior commented 4 days ago

I try to make a standalone parser code, which can parse something like "A=B;".

see below:

#include "parserlib.hpp"

#include <iostream>
#include <vector>
#include <string>
#include <memory>
#include <cassert>

// using namespace parserlib;
using namespace parserlib::core;
// using namespace parserlib::cfe;

enum class TokenKind {
    A,
    B,
    C,
    Equal,
    Semicolumn
};

struct Token {
    TokenKind kind;
    std::string lexeme;
    int row;
    int column;

    bool operator == (TokenKind tk) const {
        return kind == tk;
    }
};

std::vector<Token> tokens;

enum class ASTID {
    Assignment,
    Declaration
};

// try to parse the "A = B;" statement
// try to parse the "A B;" statement
const auto grammar
    =   *(TokenKind::A >> TokenKind::Equal >>  TokenKind::B >> TokenKind::Semicolumn) ->* ASTID::Assignment
    |   *(TokenKind::A >> TokenKind::B >> TokenKind::Semicolumn) ->* ASTID::Declaration
    ;

class MyAST {
public:
    typedef ASTID ASTID;

    typedef std::vector<Token> Source;

    ASTID ID;
    std::vector<std::shared_ptr<MyAST>> children;

    MyAST(ASTID id, std::vector<Token>::const_iterator start, std::vector<Token>::const_iterator end)
        : ID(id)
    {
    }

    void addChild(const std::shared_ptr<MyAST>& child) {
        children.push_back(child);
    }

    // Recursive function to print the AST tree
    void printTree(int depth = 0) const {
        // Print the current node with indentation based on the depth
        std::string indent(depth * 2, ' ');
        std::cout << indent << "Node: " << astIDToString(ID) << std::endl;

        // Recursively print children
        for (const auto& child : children) {
            child->printTree(depth + 1);
        }
    }

//    Assignment,
//    Declaration
    // Helper function to convert ASTID enum to string for printing
    std::string astIDToString(ASTID id) const {
        switch (id) {
            case ASTID::Assignment: return "Assignment";
            case ASTID::Declaration: return "Declaration";
            default: return "Unknown";
        }
    }
};

std::vector<std::shared_ptr<MyAST>> ast;

class Error {
public:
    std::vector<Token>::const_iterator START;

    Error(int id, std::vector<Token>::const_iterator start, std::vector<Token>::const_iterator end)
        : START(start)
    {
    }

    bool operator < (const Error& err) const {
        return START < err.START;
    }
};

int main()
{
    std::vector<Error> errors;

    std::vector<Token> input;
    input.push_back(Token{ TokenKind::A, "", 0, 0 });
    input.push_back(Token{ TokenKind::Equal, "", 0, 0 });
    input.push_back(Token{ TokenKind::B, "", 0, 0 });
    input.push_back(Token{ TokenKind::Semicolumn, "", 0, 0 });

    input.push_back(Token{ TokenKind::A, "", 0, 0 });
    input.push_back(Token{ TokenKind::B, "", 0, 0 });
    input.push_back(Token{ TokenKind::Semicolumn, "", 0, 0 });

    parserlib::cfe::parse(input, grammar, ast, errors);

    // Draw the AST tree in the console
    std::cout << "AST Tree:" << std::endl;
    for (const auto& node : ast) {
        node->printTree();  // Print the AST tree starting from each root node
    }

    return 0;
}

I got the build error:

-------------- Build: Debug in test_parser_lib (compiler: GNU GCC Compiler)---------------

[ 50.0%] g++.exe -Wall -fexceptions -g -Iinclude -c main.cpp -o obj\Debug\main.o
[100.0%] g++.exe  -o bin\Debug\test_parser_lib.exe obj\Debug\main.o   
main.cpp:42:24: error: no match for 'operator>>' (operand types are 'TokenKind' and 'TokenKind')
   42 |     =   *(TokenKind::A >> TokenKind::Equal >>  TokenKind::B >> TokenKind::Semicolumn) ->* ASTID::Assignment
      |           ~~~~~~~~~~~~ ^~ ~~~~~~~~~~~~~~~~
      |                      |               |
      |                      TokenKind       TokenKind
main.cpp:43:24: error: no match for 'operator>>' (operand types are 'TokenKind' and 'TokenKind')
   43 |     |   *(TokenKind::A >> TokenKind::B >> TokenKind::Semicolumn) ->* ASTID::Declaration
      |           ~~~~~~~~~~~~ ^~ ~~~~~~~~~~~~
      |                      |               |
      |                      TokenKind       TokenKind
Process terminated with status 1 (0 minute(s), 0 second(s))
2 error(s), 0 warning(s) (0 minute(s), 0 second(s))

So, the error line comes from here:

// try to parse the "A = B;" statement
// try to parse the "A B;" statement
const auto grammar
    =   *(TokenKind::A >> TokenKind::Equal >>  TokenKind::B >> TokenKind::Semicolumn) ->* ASTID::Assignment
    |   *(TokenKind::A >> TokenKind::B >> TokenKind::Semicolumn) ->* ASTID::Declaration
    ;

Can you help to solve this issue? It looks like the TokenKind can not be used as a "term"?

But in your example code:

const auto grammar
    = *(TokenKind::A->*ASTID::A
    |   TokenKind::B->*ASTID::B
    |   TokenKind::C->*ASTID::C)
;

This works OK.

Thanks.

asmwarrior commented 4 days ago

Oh, the grammar could be:

// try to parse the "A = B;" statement
// try to parse the "A B;" statement
const auto grammar
    =   *(TokenKind::A >> TokenKind::Equal >>  TokenKind::B >> TokenKind::Semicolumn ->* ASTID::Assignment)
    |   *(TokenKind::A >> TokenKind::B >> TokenKind::Semicolumn ->* ASTID::Declaration)
    ;

See the parenthesis position changes, but still the same build error.

asmwarrior commented 4 days ago
    const auto grammar
        = *(TokenKind::A >> TokenKind::Equal ->*ASTID::Assignment
        |   TokenKind::C->*ASTID::Declaration)
        ;

The above code compiles correctly without error.

But the below code has build errors:

    const auto grammar
        = *(TokenKind::A >> TokenKind::Equal >> TokenKind::B ->*ASTID::Assignment
        |   TokenKind::C->*ASTID::Declaration)
        ;

I'm not sure why.

The former has one >> and the later has two >> operator.

axilmar commented 2 days ago

The following code:

TokenKind::A >> TokenKind::Equal >> TokenKind::B >> TokenKind::Semicolumn

does not contain anything from parserlib, and so the compiler thinks it's a declaration of right shifts.

You should put at least one term call in that, like this:

term(TokenKind::A) >> TokenKind::Equal >> TokenKind::B >> TokenKind::Semicolon

On Thu, Oct 17, 2024 at 11:57 AM ollydbg @.***> wrote:

I try to make a standalone parser code, which can parse something like "A=B;".

see below:

include "parserlib.hpp"

include

include

include

include

include

// using namespace parserlib; using namespace parserlib::core; // using namespace parserlib::cfe;

enum class TokenKind { A, B, C, Equal, Semicolumn };

struct Token { TokenKind kind; std::string lexeme; int row; int column;

bool operator == (TokenKind tk) const {
    return kind == tk;
}

};

std::vector tokens;

enum class ASTID { Assignment, Declaration };

// try to parse the "A = B;" statement // try to parse the "A B;" statement const auto grammar = (TokenKind::A >> TokenKind::Equal >> TokenKind::B >> TokenKind::Semicolumn) -> ASTID::Assignment | (TokenKind::A >> TokenKind::B >> TokenKind::Semicolumn) -> ASTID::Declaration ;

class MyAST { public: typedef ASTID ASTID;

typedef std::vector<Token> Source;

ASTID ID;
std::vector<std::shared_ptr<MyAST>> children;

MyAST(ASTID id, std::vector<Token>::const_iterator start, std::vector<Token>::const_iterator end)
    : ID(id)
{
}

void addChild(const std::shared_ptr<MyAST>& child) {
    children.push_back(child);
}

// Recursive function to print the AST tree
void printTree(int depth = 0) const {
    // Print the current node with indentation based on the depth
    std::string indent(depth * 2, ' ');
    std::cout << indent << "Node: " << astIDToString(ID) << std::endl;

    // Recursively print children
    for (const auto& child : children) {
        child->printTree(depth + 1);
    }
}

// Assignment, // Declaration // Helper function to convert ASTID enum to string for printing std::string astIDToString(ASTID id) const { switch (id) { case ASTID::Assignment: return "Assignment"; case ASTID::Declaration: return "Declaration"; default: return "Unknown"; } } };

std::vector<std::shared_ptr> ast;

class Error { public: std::vector::const_iterator START;

Error(int id, std::vector<Token>::const_iterator start, std::vector<Token>::const_iterator end)
    : START(start)
{
}

bool operator < (const Error& err) const {
    return START < err.START;
}

};

int main() { std::vector errors;

std::vector<Token> input;
input.push_back(Token{ TokenKind::A, "", 0, 0 });
input.push_back(Token{ TokenKind::Equal, "", 0, 0 });
input.push_back(Token{ TokenKind::B, "", 0, 0 });
input.push_back(Token{ TokenKind::Semicolumn, "", 0, 0 });

input.push_back(Token{ TokenKind::A, "", 0, 0 });
input.push_back(Token{ TokenKind::B, "", 0, 0 });
input.push_back(Token{ TokenKind::Semicolumn, "", 0, 0 });

parserlib::cfe::parse(input, grammar, ast, errors);

// Draw the AST tree in the console
std::cout << "AST Tree:" << std::endl;
for (const auto& node : ast) {
    node->printTree();  // Print the AST tree starting from each root node
}

return 0;

}

I got the build error:

-------------- Build: Debug in test_parser_lib (compiler: GNU GCC Compiler)---------------

[ 50.0%] g++.exe -Wall -fexceptions -g -Iinclude -c main.cpp -o obj\Debug\main.o [100.0%] g++.exe -o bin\Debug\test_parser_lib.exe obj\Debug\main.o main.cpp:42:24: error: no match for 'operator>>' (operand types are 'TokenKind' and 'TokenKind') 42 = (TokenKind::A >> TokenKind::Equal >> TokenKind::B >> TokenKind::Semicolumn) -> ASTID::Assignment ~~~~ ^~ ~~~~
TokenKind TokenKind
main.cpp:43:24: error: no match for 'operator>>' (operand types are 'TokenKind' and 'TokenKind') 43 (TokenKind::A >> TokenKind::B >> TokenKind::Semicolumn) -> ASTID::Declaration ~~~~ ^~ ~~~~
TokenKind TokenKind

Process terminated with status 1 (0 minute(s), 0 second(s)) 2 error(s), 0 warning(s) (0 minute(s), 0 second(s))

So, the error line comes from here:

// try to parse the "A = B;" statement // try to parse the "A B;" statement const auto grammar = (TokenKind::A >> TokenKind::Equal >> TokenKind::B >> TokenKind::Semicolumn) -> ASTID::Assignment | (TokenKind::A >> TokenKind::B >> TokenKind::Semicolumn) -> ASTID::Declaration ;

Can you help to solve this issue? It looks like the TokenKind can not be used as a "term"?

But in your example code:

const auto grammar = (TokenKind::A->ASTID::A | TokenKind::B->ASTID::B | TokenKind::C->ASTID::C) ;

This works OK.

Thanks.

— Reply to this email directly, view it on GitHub https://github.com/axilmar/parserlib/issues/16#issuecomment-2418958112, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAESDFBJAJIO3YMTQNHK4JTZ353W5AVCNFSM6AAAAABPYODGFOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDIMJYHE2TQMJRGI . You are receiving this because you commented.Message ID: @.***>

axilmar commented 2 days ago

I am preparing a new version of the library, so these issues will be resolved albeit in a different manner.

At the moment, rename your token class to MyToken or use a typedef to distinguish between the two.

On Thu, Oct 17, 2024 at 10:59 AM ollydbg @.***> wrote:

I see another issue:

In the testing code of a standalone parser, there are some code like:

struct Token { TokenKind kind; std::string lexeme; int row; int column;

bool operator == (TokenKind tk) const {
    return kind == tk;
}

};

std::vector tokens;

And in the library's header file, there are same class Token, see here:

namespace parserlib::cfe {

/**
 * A token.
 *
 * It is created from tokenizing an input, and it is fed to a parser to parse a language grammar.
 *
 * @param TokenID_ id of token.
 *
 * @param Source_ source for the token.
 */
template <class TokenID_ = int, class Source_ = core::SourceString<>> class Token {
public:
    /**
     * Token id type.
     */
    typedef TokenID_ TokenID;

    /**
     * Source type.
     */
    typedef Source_ Source;

    /**
     * Source iterator type.
     */
    typedef typename Source::const_iterator SourceIterator;

    /**
     * Source view type.
     */
    typedef std::basic_string_view<typename Source::value_type> StringView;

    /**
     * Constructor.
     * @param id id of token.
     * @param startPosition start position of the token into the source.
     * @param endPosition end position of the the token into the source.
     */
    Token(const TokenID& id, const SourceIterator& startPosition, const SourceIterator& endPosition)
        : m_id(id)
        , m_startPosition(startPosition)
        , m_endPosition(endPosition)
    {
    }

    /**
     * Returns the token id.
     * @return the token id.
     */
    const TokenID& getID() const {
        return m_id;
    }

    /**
     * Returns the start position.
     * @return the start position.
     */
    const SourceIterator& getStartPosition() const {
        return m_startPosition;
    }

    /**
     * Returns the end position.
     * @return the end position.
     */
    const SourceIterator& getEndPosition() const {
        return m_endPosition;
    }

    /**
     * Returns the source that correponds to this token.
     * @return the source that correponds to this token.
     */
    StringView getSource(size_t maxChars = -1) const {
        const auto* src = &*m_startPosition;
        const size_t size = std::min(maxChars, (size_t)(m_endPosition - m_startPosition));
        return StringView(src, size);
    }

    /**
     * Checks if this token has the given id.
     * @param id id to check.
     * @return true if this token has the given id, false otherwise.
     */
    bool operator == (const TokenID& id) const {
        return m_id == id;
    }

    /**
     * Checks if this token does not have the given id.
     * @param id id to check.
     * @return true if this token does not have the given id, false otherwise.
     */
    bool operator != (const TokenID& id) const {
        return m_id != id;
    }

private:
    TokenID m_id;
    SourceIterator m_startPosition;
    SourceIterator m_endPosition;
};

So the names will get conflict if you use the

using namespace parserlib::cfe;

— Reply to this email directly, view it on GitHub https://github.com/axilmar/parserlib/issues/16#issuecomment-2418833499, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAESDFFF3ODSKHZOKCOU25DZ35U6JAVCNFSM6AAAAABPYODGFOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDIMJYHAZTGNBZHE . You are receiving this because you commented.Message ID: @.***>

axilmar commented 2 days ago

Neither is good without a term() call, as I told you in previous answer.

On Thu, Oct 17, 2024 at 1:00 PM ollydbg @.***> wrote:

const auto grammar
    = *(TokenKind::A >> TokenKind::Equal ->*ASTID::Assignment
    |   TokenKind::C->*ASTID::Declaration)
    ;

The above code compiles correctly without error.

But the below code has build errors:

const auto grammar
    = *(TokenKind::A >> TokenKind::Equal >> TokenKind::B ->*ASTID::Assignment
    |   TokenKind::C->*ASTID::Declaration)
    ;

I'm not sure why.

The former has one >> and the later has two >> operator.

— Reply to this email directly, view it on GitHub https://github.com/axilmar/parserlib/issues/16#issuecomment-2419094956, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAESDFDGNP5QUIASCUQY373Z36DE7AVCNFSM6AAAAABPYODGFOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDIMJZGA4TIOJVGY . You are receiving this because you commented.Message ID: @.***>

asmwarrior commented 2 days ago

Thanks for the reply. Add the term() function call for the first Token in the grammar solved my problem.

Here is the full source code:

#include "parserlib.hpp"

#include <iostream>
#include <vector>
#include <string>
#include <memory>
#include <cassert>

// using namespace parserlib;
using namespace parserlib::core;
// using namespace parserlib::cfe;

enum class TokenKind {
    A,
    B,
    C,
    Equal,
    Semicolumn
};

struct Token {
    TokenKind kind;
    std::string lexeme;
    int row;
    int column;

    bool operator == (TokenKind tk) const {
        return kind == tk;
    }
};

std::vector<Token> tokens;

enum class ASTID {
    Assignment,
    Declaration
};

// try to parse the "A = B;" statement
// try to parse the "A B;" statement
const auto grammar
    =   *(term(TokenKind::A) >> TokenKind::Equal >>  TokenKind::B >> TokenKind::Semicolumn ->* ASTID::Assignment
         | term(TokenKind::A) >> TokenKind::B >> TokenKind::Semicolumn ->* ASTID::Declaration)
    ;

class MyAST {
public:
    typedef ASTID ASTID;

    typedef std::vector<Token> Source;

    ASTID ID;
    std::vector<std::shared_ptr<MyAST>> children;

    MyAST(ASTID id, std::vector<Token>::const_iterator start, std::vector<Token>::const_iterator end)
        : ID(id)
    {
    }

    void addChild(const std::shared_ptr<MyAST>& child) {
        children.push_back(child);
    }

    // Recursive function to print the AST tree
    void printTree(int depth = 0) const {
        // Print the current node with indentation based on the depth
        std::string indent(depth * 2, ' ');
        std::cout << indent << "Node: " << astIDToString(ID) << std::endl;

        // Recursively print children
        for (const auto& child : children) {
            child->printTree(depth + 1);
        }
    }

//    Assignment,
//    Declaration
    // Helper function to convert ASTID enum to string for printing
    std::string astIDToString(ASTID id) const {
        switch (id) {
            case ASTID::Assignment: return "Assignment";
            case ASTID::Declaration: return "Declaration";
            default: return "Unknown";
        }
    }
};

std::vector<std::shared_ptr<MyAST>> ast;

class Error {
public:
    std::vector<Token>::const_iterator START;

    Error(int id, std::vector<Token>::const_iterator start, std::vector<Token>::const_iterator end)
        : START(start)
    {
    }

    bool operator < (const Error& err) const {
        return START < err.START;
    }
};

int main()
{
    std::vector<Error> errors;

    std::vector<Token> input;
    input.push_back(Token{ TokenKind::A, "", 0, 0 });
    input.push_back(Token{ TokenKind::Equal, "", 0, 0 });
    input.push_back(Token{ TokenKind::B, "", 0, 0 });
    input.push_back(Token{ TokenKind::Semicolumn, "", 0, 0 });

    input.push_back(Token{ TokenKind::A, "", 0, 0 });
    input.push_back(Token{ TokenKind::B, "", 0, 0 });
    input.push_back(Token{ TokenKind::Semicolumn, "", 0, 0 });

    parserlib::cfe::parse(input, grammar, ast, errors);

    // Draw the AST tree in the console
    std::cout << "AST Tree:" << std::endl;
    for (const auto& node : ast) {
        node->printTree();  // Print the AST tree starting from each root node
    }

    return 0;
}

And here is the result of the running code:

AST Tree:
Node: Assignment
Node: Declaration

I think I need to find a better way to print the ast tree inside the console window.