使用ANTLR4

时间:2016-09-28 18:24:10

标签: tsql parsing antlr4

我目前正在开发一个T-SQL解析器,它能够在我的学校项目的数据库中映射查询。到目前为止,我已经设法解析了大部分内容,但我遇到了一个我似乎无法解决的问题。我使用带有tsql.g4语法的C#和ANTLR4。

如何访问表达式?我想知道我在选择中并且我有某种表达方式,但表达式是什么样的表达式?是否可以从select_statement中仅提取列名,模式(如果有)和数据库(如果有)?

每当我尝试从c#代码

访问表达式

上下文:GrammarSQLParser.Dml_clauseContext context     context.select_statement()。query_expression()。query_specification()。select_list中()。select_list_elem()。表达式()

我只获取CopyFrom()方法,我没有任何full_column_name()方法可以进一步访问table_name()等等。

edit1:经过仔细检查后,表达式是一个column_ref_expression,但如何从表达式中访问它?他们是不同的对象..

这是查询:

select p.BusinessEntityID,p.FirstName,p.LastName,adresstbl.* from person.Person as p 
join (select bea.BusinessEntityID, adr.AddressLine1, adr.AddressLine2, adr.City, adr.PostalCode from person.BusinessEntityAddress as bea 
join person.Address as adr
on bea.AddressID = adr.AddressID )
as adresstbl 
on not p.BusinessEntityID != adresstbl.BusinessEntityID order by p.BusinessEntityID

这是我的解析树:

  

Lisp Parse Tree:(tsql_file(batch(sql_clauses(sql_clause)   (dml_clause(select_statement(query_expression(query_specification   select(select_list(select_list_elem(表达式)(full_column_name   (table_name(id(simple_id p)))。 (id(simple_id BusinessEntityID)))))   ,(select_list_elem(表达式(full_column_name(table_name(id   (simple_id p)))。 (id(simple_id FirstName))))),(select_list_elem   (表达式(full_column_name(table_name(id(simple_id p)))。(id   (simple_id LastName))))), (select_list_elem(table_name(id)   (simple_id adresstbl)))。 *))来自(table_sources(table_source。)   (table_source_item_joined(table_source_item(table_name_with_hint   (table_name(id(simple_id person))。(id(simple_id Person))))   (as_table_alias as(table_alias(id(simple_id p)))))(join_part join   (table_source(table_source_item_joined(table_source_item   (derived_table(子查询)(select_statement(query_expression(   (query_expression(query_specification select(select_list   (select_list_elem(expression(full_column_name)(table_name(id   (simple_id bea)))。 (id(simple_id BusinessEntityID))))),   (select_list_elem(expression(full_column_name)(table_name(id   (simple_id adr)))。 (id(simple_id AddressLine1))))),   (select_list_elem(expression(full_column_name)(table_name(id   (simple_id adr)))。 (id(simple_id AddressLine2))))),   (select_list_elem(expression(full_column_name)(table_name(id   (simple_id adr)))。 (id(simple_id City))))),(select_list_elem   (表达式(full_column_name(table_name(id(simple_id adr)))。(id   (simple_id PostalCode))))))from(table_sources(table_source   (table_source_item_joined(table_source_item(table_name_with_hint   (table_name(id(simple_id person))。(id(simple_id   BusinessEntityAddress))))(as_table_alias as(table_alias(id   (simple_id bea)))))(join_part join(table_source   (table_source_item_joined(table_source_item(table_name_with_hint   (table_name(id(simple_id person))。(id(simple_id Address))))   (as_table_alias as(table_alias(id(simple_id adr)))))))on   (search_condition(search_condition_and(search_condition_not   (谓词(表达式(full_column_name)(table_name(id(simple_id   bea)))。 (id(simple_id AddressID))))(comparison_operator =)   (表达式(full_column_name(table_name(id(simple_id adr)))。(id   (simple_id AddressID)))))))))))))))))))(as_table_alias as   (table_alias(id(simple_id adresstbl))))))))(search_condition   (search_condition_and(search_condition_not not(谓词(表达式   (full_column_name(table_name(id(simple_id p)))。(id(simple_id   BusinessEntityID))))(comparison_operator!=)(表达式   (full_column_name(table_name(id(simple_id adresstbl)))。(id   (simple_id BusinessEntityID))))))))))))))(order_by_clause order by   (order_by_expression(表达式(full_column_name(table_name(id   (simple_id p)))。 (id(simple_id BusinessEntityID))))))))))))

1 个答案:

答案 0 :(得分:1)

expression可能是很多事情之一。如果你看一下语法,你会看到

expression
    : DEFAULT                                                  #primitive_expression
    | NULL                                                     #primitive_expression
    | LOCAL_ID                                                 #primitive_expression
    | constant                                                 #primitive_expression
    | function_call                                            #function_call_expression
    | expression COLLATE id                                    #function_call_expression
    | case_expr                                                #case_expression
    | full_column_name                                         #column_ref_expression
    | '(' expression ')'                                       #bracket_expression
    | '(' subquery ')'                                         #subquery_expression
    | '~' expression                                           #unary_operator_expression

    | expression op=('*' | '/' | '%') expression               #binary_operator_expression
    | op=('+' | '-') expression                                #unary_operator_expression
    | expression op=('+' | '-' | '&' | '^' | '|') expression   #binary_operator_expression
    | expression comparison_operator expression                #binary_operator_expression
    ;

你需要弄清楚它们是哪些东西。在您的情况下,它是column_ref_expression,在这种情况下,您需要将其投放到Column_ref_expressionContext,然后您才能访问full_column_name

有各种方法可以确定它是什么,或者你可以假设你只想支持有限的语法子集。