Antlr4 ANTLR 4错误50-字符不匹配';i';期待';{';

Antlr4 ANTLR 4错误50-字符不匹配';i';期待';{';,antlr4,Antlr4,这里是ANTLR4新手 我正在尝试创建我的第一个ANTLR4语法——一个小小的Oracle SQL*加载器——但似乎无法走出起点 当我通过别名antlr4运行语法时,会收到以下错误消息: error(50): HQLLDR.g4::: syntax error: mismatched character 'i' expecting '{' 我认为这个错误是由于使用了诸如OPTIONS之类的ANTLR4关键字造成的,所以我将代码改为使用OPTS,但是错误仍然存在 以下是语法: grammar H

这里是ANTLR4新手

我正在尝试创建我的第一个ANTLR4语法——一个小小的Oracle SQL*加载器——但似乎无法走出起点

当我通过别名antlr4运行语法时,会收到以下错误消息:

error(50): HQLLDR.g4::: syntax error: mismatched character 'i' expecting '{'
我认为这个错误是由于使用了诸如OPTIONS之类的ANTLR4关键字造成的,所以我将代码改为使用OPTS,但是错误仍然存在

以下是语法:

grammar HQLLDR;

hqlldr: hqlhdr hqlbody ;

hqlhdr: LOAD DATA ;

hqlbody: hql_express hql_full ;

hql_express: infile_express ;

hql_full: options infile tbldefn fielddefn datalines ;

opts: OPTS '(' opt ( ',' opt )* ')' ;
opt: skipit | database | schema ;
skipit: SKIPIT '='  DIGIT+ ;
database: DATABASE '=' OBJNM ;
schema: SCHEMA '=' OBJNM ;

infile_express: INFILE filelist_express ;
filelist_express: '(' '"' file_express '"' ')' ;
file_express: TEXT ;

infile: INFILE (DATALINES | filelist)? ;
filelist: '(' '"' file '"' ( ',' '"' file '"' )* ')' ;
file: TEXT ;

tbldefn: (TRUNCATE | APPEND | CREATE) INTO TABLE tblnm ;
tblnm: OBJNM OBJDESC? ;

fielddefn: termdefn encdefn? fieldlist ;
termdefn: TERMINATED BY DELIMITER terminators ;
terminators: (TAB|SEMICOLON|COMMA|COLON|SPACE) ;
encdefn: ENCLOSED BY ENCLOSURE enclosures ;
enclosures: (DOUBLEQUOTE|APOSTROPHE) ;
fieldlist: '(' fieldname fielddesc? fielddatatype ( ',' fieldname fielddesc? fielddatatype )* ')' ;
fieldname: OBJNM ;
fielddesc:  OBJDESC? ;
fielddatatype: (BIGINT | INT | SMALLINT | TINYINT | TIMESTAMP | STRING | FLOAT | DOUBLE) ;

datalines: ROWTEXT '\r'? '\n' ;

ROWTEXT: ~[\n\r]+ ;
LETTER:   [a-zA-Z_] ;
DIGIT:   [0-9] ;
LOAD:   [Ll][Oo][Aa][Dd] ;
DATA:   [Dd][Aa][Tt][Aa] ;
OPTS:   [Oo][Pp][Tt][Ii][Oo][Nn][Ss] ;
SKIPIT:   [Ss][Kk][Ii][Pp] ;
DATABASE:   [Dd][Aa][Tt][Aa][Bb][Aa][Ss][Ee] ;
SCHEMA:   [Ss][Cc][Hh][Ee][Mm][Aa] ;
INFILE:   [Ii][Nn][Ff][Ii][Ll][Ee] ;
DATALINES:   [Dd][Aa][Tt][Aa][Ll][Ii][Nn][Ee][Ss] ;
TRUNCATE:   [Tt][Rr][Uu][Nn][Cc][Aa][Tt][Ee] ;
APPEND:   [Aa][Pp][Pp][Ee][Nn][Dd] ;
CREATE:   [Cc][Rr][Ee][Aa][Tt][Ee] ;
INTO:   [Ii][Nn][Tt][Oo] ;
TABLE:   [Tt][Aa][Bb][Ll][Ee] ;
FIELDS:   [Ff][Ii][Ee][Ll][Dd][Ss] ;
TERMINATED:   [Tt][Ee][Rr][Mm][Ii][Nn][Aa][Tt][Ee][Dd] ;
BY:   [Bb][Yy] ;
ENCLOSED:   [Ee][Nn][Cc][Ll][Oo][Ss][Ee][Dd] ;
OBJDESC:   '(' '"' .*? '"' ')' ;
OBJNM:   LETTER+ (LETTER | DIGIT)* ;
TEXT:   ~[,\n\r"']+ ;
TAB:   [Tt][Aa][Bb] ;
SEMICOLON:   [Ss][Ee][Mm][Ii][Cc][Oo][Ll][Oo][Nn] ;
COMMA:   [Cc][Oo][Mm][Mm][Aa] ;
COLON:   [Cc][Oo][Ll][Oo][Nn] ;
SPACE:   [Ss][Pp][Aa][Cc][Ee] ;
DELIMITER:   (TAB | SEMICOLON | COMMA | COLON | SPACE) ;
DOUBLEQUOTE:   [Dd][Oo][Uu][Bb][Ll][Ee][Qq][Uu][Oo][Tt][Ee] ;
APOSTROPHE:   [Aa][Pp][Oo][Ss][Tt][Rr][Oo][Pp][Hh][Ee] ;
ENCLOSURE:   (DOUBLEQUOTE | APOSTROPHE) ;
BIGINT:   [Bb][Ii][Gg][Ii][Nn][Tt] ;
INT:   [Ii][Nn][Tt] ;
SMALLINT:   [Ss][Mm][Aa][Ll][Ll][Ii][Nn][Tt] ;
TINYINT:   [Tt][Ii][Nn][Yy][Ii][Nn][Tt] ;
TIMESTAMP:   [Tt][Ii][Mm][Ee][Ss][Tt][Aa][Mm][Pp] ;
STRING:   [Ss][Tt][Rr][Ii][Nn][Gg] ;
FLOAT:   [Ff][Ll][Oo][Aa][Tt] ;
DOUBLE:   [Dd][Oo][Uu][Bb][Ll][Ee] ;
NL:   '\r'? '\n' ;
WS:   [ \t]+ -> skip ;
任何帮助都将不胜感激

谢谢!
Scott

Oy!Nevermind!我忘记了将规则“options”更改为“opts”以及修复字段列表的问题。它编译了。:-

Oy!Nevermind!我忘记了将规则“options”更改为“opts”以及修复字段列表的问题。它编译了。:-

ANTLR的lexer以以下方式构造令牌:

  • 尝试为单个令牌使用尽可能多的字符(lexer规则)
  • 如果有两个或多个lexer规则匹配相同的字符,则让第一个定义的规则“win”
  • 根据您的lexer规则:

    ROWTEXT: ~[\n\r]+ ;
    
    输入
    “加载数据\n”
    ,很明显(或应该)只会创建2个令牌:

    ROWTEXT : 'load data'
    NL      : '\n'
    
    解析器是否试图匹配
    加载
    标记后紧跟
    数据
    标记并不重要:lexer独立于解析器运行

    您必须删除
    行文本
    ,并尝试在解析器中构造它:

    rowtext
     : ~NL+
     ;
    

    请注意,解析器规则中的
    ~
    否定标记,而不是字符。因此,它的意思是:“匹配除NL以外的一个或多个标记”。

    ANTLR的lexer以以下方式构造标记:

  • 尝试为单个令牌使用尽可能多的字符(lexer规则)
  • 如果有两个或多个lexer规则匹配相同的字符,则让第一个定义的规则“win”
  • 根据您的lexer规则:

    ROWTEXT: ~[\n\r]+ ;
    
    输入
    “加载数据\n”
    ,很明显(或应该)只会创建2个令牌:

    ROWTEXT : 'load data'
    NL      : '\n'
    
    解析器是否试图匹配
    加载
    标记后紧跟
    数据
    标记并不重要:lexer独立于解析器运行

    您必须删除
    行文本
    ,并尝试在解析器中构造它:

    rowtext
     : ~NL+
     ;
    

    请注意,解析器规则中的
    ~
    否定标记,而不是字符。因此它的意思是:“匹配除NL以外的一个或多个标记”.

    毫无疑问,它已经编译,但我高度怀疑语法是否符合您的要求。请检查我的答案。@BartKiers同意。我可能已经从我的第一个ANTLR语法中咬下了更多。再次感谢您非常有用的评论。毫无疑问,它已经编译,但我高度怀疑语法是否符合您的要求。Ch请选择我的答案。@BartKiers同意。我可能在我的第一个ANTLR语法中咬下了比我应该咬下的更多的东西。再次感谢你非常有用的评论。谢谢你的更正。正如我所说,我是一个新手,仍然难以理解lexer和解析器之间的区别。你的评论帮了我很大的忙,所以谢谢你非常感谢!谢谢你的更正。正如我所说的,我是一个新手,仍然无法理解lexer和解析器之间的区别。你的评论帮助了很多,所以非常感谢!!!!