ANTLR4 g4语法用于读取不同块中的键/值对
我是antlr的新手,我试着做简单的语法,但我没能成功。 我想解析此类文件:ANTLR4 g4语法用于读取不同块中的键/值对,antlr4,Antlr4,我是antlr的新手,我试着做简单的语法,但我没能成功。 我想解析此类文件: BEGIN HEADER CharacterSet "CP1252" END HEADER BEGIN DSJOB test "val" END DSJOB BEGIN DSJOB test "val2" END DS 工作 我用的是这种语法: grammar Hello; dsxFile : headerDeclaration? jobDeclaration* E
BEGIN HEADER
CharacterSet "CP1252"
END HEADER
BEGIN DSJOB
test "val"
END DSJOB
BEGIN DSJOB
test "val2"
END DS
工作
我用的是这种语法:
grammar Hello;
dsxFile : headerDeclaration? jobDeclaration* EOF;
headerDeclaration : 'BEGIN HEADER' param* 'END HEADER';
jobDeclaration : 'BEGIN DSJOB' subJobDeclaration* param* 'END DSJOB';
subJobDeclaration : 'BEGIN DSSUBJOB' param* 'END DSSUBJOB';
headParam
: ( 'CharacterSet'
| 'name'
) StringLiteral
;
// ANNOTATIONS
param : PNAME PVALUE;
PNAME :StringCharacters;
PVALUE :StringCharacters;
// STATEMENTS / BLOCKS
//block
// : '{' blockStatement* '}';
// LEXER
// Keywords
ABSTRACT : 'abstract';
ASSERT : 'assert';
BOOLEAN : 'boolean';
BREAK : 'break';
BYTE : 'byte';
CASE : 'case';
CATCH : 'catch';
CHAR : 'char';
CLASS : 'class';
CONST : 'const';
CONTINUE : 'continue';
DEFAULT : 'default';
DO : 'do';
DOUBLE : 'double';
ELSE : 'else';
ENUM : 'enum';
EXTENDS : 'extends';
FINAL : 'final';
FINALLY : 'finally';
FLOAT : 'float';
FOR : 'for';
IF : 'if';
GOTO : 'goto';
IMPLEMENTS : 'implements';
IMPORT : 'import';
INSTANCEOF : 'instanceof';
INT : 'int';
INTERFACE : 'interface';
LONG : 'long';
NATIVE : 'native';
NEW : 'new';
PACKAGE : 'package';
PRIVATE : 'private';
PROTECTED : 'protected';
PUBLIC : 'public';
RETURN : 'return';
SHORT : 'short';
STATIC : 'static';
STRICTFP : 'strictfp';
SUPER : 'super';
SWITCH : 'switch';
SYNCHRONIZED : 'synchronized';
THIS : 'this';
THROW : 'throw';
THROWS : 'throws';
TRANSIENT : 'transient';
TRY : 'try';
VOID : 'void';
VOLATILE : 'volatile';
WHILE : 'while';
// Boolean Literals
BooleanLiteral : 'true' | 'false';
// Character Literals
fragment
SingleCharacter
: ~['\\] ;
// String Literals
StringLiteral
: '"' StringCharacters? '"'
;
fragment
StringCharacters
: StringCharacter+
;
fragment
StringCharacter
: ~["\\]
;
// Separators
LPAREN : '(';
RPAREN : ')';
LBRACE : '{';
RBRACE : '}';
LBRACK : '[';
RBRACK : ']';
SEMI : ';';
COMMA : ',';
DOT : '.';
// Operators
ASSIGN : '=';
GT : '>';
LT : '<';
BANG : '!';
TILDE : '~';
QUESTION : '?';
COLON : ':';
EQUAL : '==';
LE : '<=';
GE : '>=';
NOTEQUAL : '!=';
AND : '&&';
OR : '||';
INC : '++';
DEC : '--';
ADD : '+';
SUB : '-';
MUL : '*';
DIV : '/';
BITAND : '&';
BITOR : '|';
CARET : '^';
MOD : '%';
ADD_ASSIGN : '+=';
SUB_ASSIGN : '-=';
MUL_ASSIGN : '*=';
DIV_ASSIGN : '/=';
AND_ASSIGN : '&=';
OR_ASSIGN : '|=';
XOR_ASSIGN : '^=';
MOD_ASSIGN : '%=';
LSHIFT_ASSIGN : '<<=';
RSHIFT_ASSIGN : '>>=';
URSHIFT_ASSIGN : '>>>=';
//
// Additional symbols not defined in the lexical specification
//
AT : '@';
ELLIPSIS : '...';
//
// Whitespace and comments
//
WS : [ \t\r\n\u000C]+ -> skip
;
COMMENT
: '/*' .*? '*/' -> skip
;
LINE_COMMENT
: '//' ~[\r\n]* -> skip
;
语法你好;
DSX文件:标题声明?职位声明*EOF;
HeaderDebration:“开始标头”参数*“结束标头”;
jobDeclaration:'BEGIN DSJOB'SubbobDeclaration*param*'END DSJOB';
SubbobDeclaration:'开始DSSUBJOB'参数*'结束DSSUBJOB';
头参数
:(“字符集”
|“姓名”
)StringLiteral
;
//注释
param:PNAME PVALUE;
PNAME:StringCharacters;
PVALUE:字符串字符;
//语句/块
//挡块
//:“{”块语句*“}”;
//雷克瑟
//关键词
摘要:“摘要”;
断言:‘断言’;
布尔:'布尔';
休息:“休息”;
字节:“字节”;
案例:“案例”;
接球:“接球”;
CHAR:‘CHAR’;
阶级:"阶级";;
常数:“常数”;
继续:"继续";;
默认:“默认”;
DO:‘DO’;
双:‘双’;
ELSE:‘ELSE’;
枚举:“枚举”;
延伸:“延伸”;
决赛:“决赛”;
最后:"最后",;
浮动:“浮动”;
因为‘为了’;
如果:‘如果’;
后藤:‘后藤’;
工具:“工具”;
进口:‘进口’;
INSTANCEOF:'INSTANCEOF';
INT:‘INT’;
接口:“接口”;
长:“长”;
本地人:“本地人”;
新:"新";;
包:"包";;
私人:"私人";;
受保护:“受保护”;
公众:"公众";;
RETURN:‘RETURN’;
短:“短”;
静态:“静态”;
STRICTFP:‘STRICTFP’;
超级:“超级”;
开关:“开关”;
SYNCHRONIZED:‘SYNCHRONIZED’;
这个:"这个",;
扔:‘扔’;
投掷:“投掷”;
暂时的:“暂时的”;
试试:‘试试’;
无效:“无效”;
挥发性:“挥发性”;
WHILE:‘WHILE’;
//布尔文字
BooleanLiteral:'真'|'假';
//字符文字
片段
单字符
: ~['\\] ;
//字符串文字
StringLiteral
:““‘字符串字符’””
;
片段
字符串字符
:字符串字符+
;
片段
字符串字符
: ~["\\]
;
//分离器
LPAREN:'(';
RPAREN:')';
LBRACE:“{”;
RBRACE:'}';
LBRACK:'[';
RBRACK:']';
半:';';
逗号:',';
点:';
//操作员
分配:'=';
GT:“>”;
LT:“>>=”;
//
//词法规范中未定义的其他符号
//
在:“@”;
省略号:“…”;
//
//空白和注释
//
WS:[\t\r\n\u000C]+->跳过
;
评论
:“/*”.*?“*/”->跳过
;
行注释
:“/”~[\r\n]*->跳过
;
但我还是遇到了这个问题:
第1行:0不匹配的输入“BEGIN HEADER\r\n\tCharacterSet”应为
{,'BEGIN HEADER','BEGIN DSJOB'}(DSX文件BEGIN
标头\r\n\t字符集“CP1252”\r\n标头\r\n
DSJOB\r\n\t测试“val”\r\n输入DSJOB)
有人能解释一下这是什么意思吗?似乎不能跳过\r\t
感谢大家的帮助!问题在于,您的输入没有按预期标记化。这是因为lexer匹配尽可能多的输入。因此,如果您查看
PNAME
规则:
PNAME : StringCharacters;
fragment StringCharacter
: ~["\\]
;
然后您会注意到输入的“beginheader\n CharacterSet”
与该规则匹配
这是错误消息所显示的内容:
不匹配的输入'BEGIN HEADER\r\n\tCharacterSet'应为{,'BEGIN HEADER','BEGIN DSJOB'}
说明:找到了标记'BEGIN HEADER\r\n\tCharacterSet'
,而解析器需要一个标记'BEGIN HEADER'
或'BEGIN DSJOB'
您可能需要在该类中添加空格、制表符和换行符:~[“\\\t\r\n]
(但这由您决定)
此外,lexer独立于解析器进行操作(解析器对生成的令牌没有影响)。lexer只是尝试匹配尽可能多的字符,每当有两个(或更多)规则匹配相同的字符时,第一个定义的规则“获胜”。根据此逻辑,然后根据以下规则:
PNAME : StringCharacters;
PVALUE : StringCharacters;
显然,规则PVALUE
永远不会匹配(仅PNAME
,因为该规则是首先定义的)
以下是如何解析示例输入:
grammar Hello;
dsxFile : headerDeclaration? jobDeclaration* EOF;
headerDeclaration : BEGIN HEADER param* END HEADER;
jobDeclaration : BEGIN DSJOB subJobDeclaration* param* END DSJOB;
subJobDeclaration : BEGIN DSSUBJOB param* END DSSUBJOB;
param : PNAME pvalue;
pvalue : STRING /* other alternaives here? */;
STRING : '"' ~["\r\n]* '"';
BEGIN : 'BEGIN';
END : 'END';
HEADER : 'HEADER';
DSJOB : 'DSJOB';
DSSUBJOB : 'DSSUBJOB';
WS : [ \t\r\n\u000C]+ -> skip;
COMMENT : '/*' .*? '*/' -> skip;
LINE_COMMENT : '//' ~[\r\n]* -> skip;
// Be sure to put this rule _after_ the rules BEGIN, END, HEADER, ...
// otherwise this rule will match those keywords instead
PNAME : ~["\\ \t\r\n]+;
当然,您需要更改它以完全满足您的需要,但这只是一个开始。请发布一个完整的、有效的语法,该语法会产生您提到的错误。添加完整语法,非常感谢您,所有内容都变得清晰,我将尝试应用此语法。