代码之家  ›  专栏  ›  技术社区  ›  Jason

正确的步行方式

  •  0
  • Jason  · 技术社区  · 8 年前

    here . jar用于生成相应的源文件(并更改了所有 NULL 到 null 在TSqlParser.cpp中,因为冲突)。我在跟踪 doc example (以及网络上的其他示例)演示了如何实现单个规则和侦听器,这些规则和侦听器工作正常。实现多个规则时会出现问题。

    #include <iostream>
    #include <antlr4-runtime/antlr4-runtime.h>
    #include "TSqlParser.h"
    #include "TSqlLexer.h"
    
    #include "listener.h"
    
    
    int main(int argc, const char* argv[])
    {
        std::ifstream stream;
        stream.open(argv[1]);
    
        antlr4::ANTLRInputStream input(stream);
        TSqlLexer lexer(&input);
        antlr4::CommonTokenStream tokens(&lexer);
        TSqlParser parser(&tokens);
    
        TreeShapeListener listener;
    
        //antlr4::tree::ParseTree *select_tree = parser.select_statement();
        antlr4::tree::ParseTree *update_tree = parser.update_statement();
    
        //antlr4::tree::ParseTreeWalker::DEFAULT.walk(&listener, select_tree);
        antlr4::tree::ParseTreeWalker::DEFAULT.walk(&listener, update_tree);
    
        return 0;
    }
    

    侦听器.h:

    #include <antlr4-runtime/antlr4-runtime.h>
    #include "TSqlParserBaseListener.h"
    
    class TreeShapeListener : public TSqlParserBaseListener
    {
    public:
    
        void enterSelect_statement(TSqlParser::Select_statementContext*) override;
        void enterUpdate_statement(TSqlParser::Update_statementContext*) override;
    };
    

    #include "listener.h"
    
    void TreeShapeListener::enterSelect_statement(TSqlParser::Select_statementContext *ctx)
    {
        std::cout << "Hello Select\n";
    }
    
    void TreeShapeListener::enterUpdate_statement(TSqlParser::Update_statementContext *ctx)
    {
        std::cout << "Hello Update\n";
    }
    

    下面是一个小测试sql文件:

    SELECT TOP 1 NAME
    FROM MYTABLE
    WHERE SEQ = 6
    
    UPDATE MYTABLE
    SET NAME = 'Bob'
    WHERE SEQ = 5
    

    输出:

    line 1:0 mismatched input 'SELECT' expecting {'UPDATE', 'WITH'}
    Hello Update
    

    如果我切换SQL语句,我将得到 Hello Update

    1 回复  |  直到 8 年前
        1
  •  3
  •   Jonas    8 年前

    如果你用

    antlr4::tree::ParseTree *update_tree = parser.update_statement();
    

    你只使用了语法的一个子集,因为你的切入点是 tsql_file . 这个 update_statement UPDATE SELECT .

    antlr4::tree::ParseTree *tsql_file_tree = parser.tsql_file();