Plsql 对于某些PL/SQL文件,PL/SQL ANTLR语法失败?

Plsql 对于某些PL/SQL文件,PL/SQL ANTLR语法失败?,plsql,antlr4,abstract-syntax-tree,Plsql,Antlr4,Abstract Syntax Tree,我正在使用ANTLR4为PL/SQL代码生成抽象语法树(AST)。对于某些查询,它可以正常工作,但对于某些代码,它只生成一个不正确的AST节点 例如: DECLARE a RAW; -- migrate to BLOB b LONG RAW; -- migrate to BLOB c LONG VARCHAR; -- migrate to LOB d LONG; -- migrate to LOB

我正在使用ANTLR4PL/SQL代码生成抽象语法树(AST)。对于某些查询,它可以正常工作,但对于某些代码,它只生成一个不正确的AST节点

例如:

DECLARE
   a   RAW;            -- migrate to BLOB
   b   LONG RAW;       -- migrate to BLOB
   c   LONG VARCHAR;   -- migrate to LOB
   d   LONG;           -- migrate to LOB
   x   VARCHAR;
   CURSOR mycur RETURN LONG;     -- should flag
   FUNCTION myfunc RETURN LONG RAW    -- should flag
   IS
      z  LONG RAW;    -- should flag
   BEGIN 
      RETURN z;
   END;  
BEGIN
   SELECT mycol, CAST(col2 AS RAW)      -- should flag
     INTO a 
     FROM mytab 
    WHERE (b IS OF TYPE(LONG RAW, RAW, VARCHAR)); -- should flag
END;
CREATE TABLE tab (
   a   RAW,            -- should flag
   b   LONG RAW,       -- should flag
   c   LONG VARCHAR,   -- should flag
   d   LONG,           -- should flag
   x   VARCHAR
);
对于此代码,它将生成以下AST:

(compilation_unit DECLARE a RAW ; b LONG RAW ; c LONG VARCHAR ; d LONG ; x VARCHAR ; CURSOR mycur RETURN LONG ; FUNCTION myfunc RETURN LONG RAW IS z LONG RAW ; BEGIN RETURN z ; END ; BEGIN SELECT mycol , CAST ( col2 AS RAW ) INTO a FROM mytab WHERE ( b IS OF TYPE ( LONG RAW , RAW , VARCHAR ) ) ; END ; CREATE TABLE tab ( a RAW , b LONG RAW , c LONG VARCHAR , d LONG , x VARCHAR ) ;)
这只是编译单元节点中的给定代码

但如果我给出了相同的代码,但没有声明部分,它会给出很好的AST

对于此代码:

FUNCTION myfunc RETURN LONG RAW    -- should flag
   IS
      z  LONG RAW;    -- should flag
   BEGIN 
      RETURN z;
   END;  
BEGIN
   SELECT mycol, CAST(col2 AS RAW)      -- should flag
     INTO a 
     FROM mytab 
    WHERE (b IS OF TYPE(LONG RAW, RAW, VARCHAR)); -- should flag
END;
CREATE TABLE tab (
   a   RAW,            -- should flag
   b   LONG RAW,       -- should flag
   c   LONG VARCHAR,   -- should flag
   d   LONG,           -- should flag
   x   VARCHAR
);
它给出了这个AST:

(compilation_unit (unit_statement (create_function_body FUNCTION (function_name (id (id_expression (regular_id myfunc)))) RETURN (type_spec (datatype (native_datatype_element LONG RAW))) IS (declare_spec (variable_declaration (variable_name (id_expression (regular_id z))) (type_spec (datatype (native_datatype_element LONG RAW))) ;)) (body BEGIN (seq_of_statements (statement (return_statement RETURN (condition (expression (logical_and_expression (negated_expression (equality_expression (multiset_expression (relational_expression (compound_expression (concatenation (additive_expression (multiply_expression (datetime_expression (model_expression (unary_expression (atom (general_element (general_element_part (id_expression (regular_id z))))))))))))))))))))) ;) END) ;)) BEGIN (unit_statement (data_manipulation_language_statements (select_statement (subquery (subquery_basic_elements (query_block SELECT (selected_element (select_list_elements (expression (logical_and_expression (negated_expression (equality_expression (multiset_expression (relational_expression (compound_expression (concatenation (additive_expression (multiply_expression (datetime_expression (model_expression (unary_expression (atom (general_element (general_element_part (id_expression (regular_id mycol)))))))))))))))))))) , (selected_element (select_list_elements (expression (logical_and_expression (negated_expression (equality_expression (multiset_expression (relational_expression (compound_expression (concatenation (additive_expression (multiply_expression (datetime_expression (model_expression (unary_expression (standard_function CAST ( (concatenation_wrapper (concatenation (additive_expression (multiply_expression (datetime_expression (model_expression (unary_expression (atom (general_element (general_element_part (id_expression (regular_id col2)))))))))))) AS (type_spec (datatype (native_datatype_element RAW))) ))))))))))))))))) (into_clause INTO (variable_name (id_expression (regular_id a)))) (from_clause FROM (table_ref_list (table_ref (table_ref_aux (dml_table_expression_clause (tableview_name (id (id_expression (regular_id mytab))))))))) (where_clause WHERE (condition_wrapper (expression (logical_and_expression (negated_expression (equality_expression (multiset_expression (relational_expression (compound_expression (concatenation (additive_expression (multiply_expression (datetime_expression (model_expression (unary_expression (atom ( (expression_or_vector (expression (logical_and_expression (negated_expression (equality_expression (multiset_expression (relational_expression (compound_expression (concatenation (additive_expression (multiply_expression (datetime_expression (model_expression (unary_expression (atom (general_element (general_element_part (id_expression (regular_id b)))))))))))))) IS OF TYPE ( (type_spec (datatype (native_datatype_element LONG RAW))) , (type_spec (datatype (native_datatype_element RAW))) , (type_spec (datatype (native_datatype_element VARCHAR))) )))))) ))))) ; END ;)))))))))))))))))) unit_statement (unit_statement CREATE TABLE tab) (unit_statement (data_manipulation_language_statements (select_statement (subquery (subquery_basic_elements ( (subquery (subquery_basic_elements a RAW , b LONG RAW , c LONG VARCHAR , d LONG , x VARCHAR)) )) ;)))) <EOF>)
(编译单元(单元语句)(创建函数)体函数(函数名(id(id\u表达式(regular\u id myfunc)))返回(类型规格(datatype(native\u datatype\u element LONG RAW)))是(声明规格(变量声明)(变量名(id\u表达式(regular\u id z))(类型规格(datatype(native\u datatype\u element LONG RAW))))(body BEGIN(seq)of_statements(statement)(语句)return(语句)return(条件)expression(表达式)(逻辑表达式)and(表达式)(否定表达式)(相等表达式)(关系表达式)(复合表达式)(级联表达式)(加法表达式)(乘法表达式)(日期时间表达式)(模型表达式)(一元表达式)(原子(通用元素(通用元素)结束)开始(单元语句(数据操作语言语句)(选择语句)(子查询(子查询)基本元素(查询块选择(选择元素)(选择列表)元素(表达式(逻辑元素)和否定表达式(等式表达式(多集表达式(关系表达式)(复合表达式(加性表达式)(加性表达式)(一元表达式)(原子)(通用元素(通用元素)(通用元素)部分(id表达式(正则元素)(mycol‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘表达式(逻辑表达式和否定表达式)相等表达式(关系表达式)复合表达式(加性表达式)日期时间表达式(模型表达式)一元表达式(标准函数转换(将_表达式(datetime_表达式(model_表达式(一元_表达式)(atom)(general_元素(general_元素)部分(id_表达式(regular_id col2‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘(table_ref)(table_ref_aux)(dml_table_expression_子句)(tableview_name(id)(id_expression(regular_id mytab‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘)’))(where_子句where(condition_wrapper)(条件_wrapper)(表达式(逻辑_表达式)和_表达式(否定的_表达式)(相等的_表达式(关系_表达式例如:表示一元表达式(原子表达式)或表示向量(表示逻辑表达式)和表示否定的表达式(相等的表达式)或表示关系的表达式(复合表达式)或表示连接的表达式(相加的表达式)或表示否定的表达式(表示否定的表达式(一元表达式(atom(general_元素(general_元素(general_元素)部分(id_表达式(regular_id b!!!!!!!!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!(unit_语句创建表选项卡)(unit_语句(数据处理_语言_语句)(选择_语句(子查询(子查询)基本元素((子查询(子查询基本元素a RAW,b LONG RAW,c LONG VARCHAR,d LONG,x VARCHAR))));))
因此,PL/SQL语法文件中似乎缺少了一些关键字(规则),比如declare


有没有办法找到更新的plsql.g4文件或者我需要自己添加这些规则?

问题似乎实际上是plsql antlr语法不支持LONG VARCHAR数据类型,在这一部分:“c LONG VARCHAR;”

它导致声明被误解为过程调用,从而打乱了其余的解析


我在语法github中发现了一个问题:

第一个“AST”(编译单元声明a…)真的是AST吗?在我看来,它只是一个字符串。这些语法是开源的,这是一种有趣的方式,可以说“如果你不喜欢它的功能,你可以修复它”。是的。这是从toStringTree()返回的AST的字符串表示形式方法,我询问是否可以找到另一个plsql.g4文件(一个更新的文件,完成了更多规则)?顺便说一句,谢谢您的回复。@chathurawijewera有一个更为最新的ANTLR 3.3 PL/SQL语法分支,它有额外的修复,包括一些用于声明的修复。在最近的检查中,我猜语法将声明作为字符串,用于此操作的词汇定义没有正确检测到它的结尾。现在您的问题是如果你不喜欢的话就把它修好。