ANTLR 正确检测第一行模式
ANTLR properly detecting mode for 1st line
我有以下解析器
parser grammar T5Parser ;
options {
tokenVocab = T5Lexer ;
}
root: line (EOL? line)* EOL? EOF;
line: commandLine | dataLine ;
dataLine: CDataLine;
commandLine: StartCmd+ command ;
command
: halt
| note
| read
| end
;
halt : CHALT ;
end : CEND DataLine? ;
note : CNOTE DataLine? ;
read : CREAD fileName=StringLiteral ;
和词法分析器
lexer grammar T5Lexer ;
StartCmd: '@';
CDataLine: BOL ~'@' ~[\r\n]+;
EOL: EOL_F -> mode(DEFAULT_MODE);
WS: [ \t]+ -> channel(HIDDEN);
BOL : [\r\n\f]+ ;
DOT: [.];
COMMA: ',';
CHALT : 'HALT' ;
CEND : 'END' -> pushMode(DataMode);
CNOTE : 'NOTE' -> pushMode(DataMode);
CREAD : 'READ';
StringLiteral : DblQuotedString | SglQuotedString;
fragment DblQuotedString : [C]*'"' ( '\'. | '""' | ~('"'| '\') )* '"';
fragment SglQuotedString : [C]*'\'' ('\'. | '\'\'' | ~('\'' | '\'))* '\'';
fragment BackQuotedString : [C]*'`' ( '\'. | '``' | ~('`'|'\'))* '`';
//=======================================
mode DataMode ;
DmPOP : [ ,] -> popMode;
DmEOL: EOL_F -> type(EOL), popMode;
DataLine: ( ~[\r\n]*? '-' EOL_F)* ~[\r\n]+;
//=======================================
fragment NL: '\r'? '\n';
fragment EOL_F: [ ]* NL;
解析语法的以下方面工作正常
命令以@
开头
命令可以有参数(这里以READ为例)或者可选
评论
不以@开头的行是“自由格式”内联数据
按原样消费
示例输入
@NOTE
@NOTE with data
@READ 'file.one'
Test data line
@END
@HALT
也许有更好的方法来匹配“行不以某物开头”,唉,这是我经过数小时的搜索所能想到的最好的方法,但是有了这个解决方案
我无法理解的方面是当“自由格式数据”出现在输入的第一行并且没有 BOL 时。
关于如何解决这个问题的任何提示?
TIA - 亚历克斯
像这样的东西就可以了:
lexer grammar T5Lexer;
CommandStart
: '@' -> mode(CommandMode)
;
DataLine
: ~[@\r\n] ~[\r\n]*
;
EOL
: [ \t]* ( '\r'? '\n' | '\r' )
;
mode CommandMode;
HALT : 'HALT' ;
END : 'END' -> mode(DEFAULT_MODE);
NOTE : 'NOTE' -> mode(DEFAULT_MODE);
READ : 'READ';
Spaces : [ \t]+ -> skip;
StringLiteral : '\'' ( '\'\'' | ~['\r\n] )* '\'';
CM_NewLine : EOL -> type(EOL), mode(DEFAULT_MODE);
使用语法分析器:
parser grammar T5Parser;
options {
tokenVocab=T5Lexer;
}
root
: line ( EOL+ line )* EOL* EOF
;
line
: commandLine
| DataLine
;
commandLine
: CommandStart command
;
command
: halt
| note
| read
| end
;
halt : HALT;
end : END DataLine?;
note : NOTE DataLine?;
read : READ StringLiteral;
这将解析输入:
first line
@NOTE
@NOTE with data
@READ 'file.one'
Test data line
@END
@HALT
像这样:
我有以下解析器
parser grammar T5Parser ;
options {
tokenVocab = T5Lexer ;
}
root: line (EOL? line)* EOL? EOF;
line: commandLine | dataLine ;
dataLine: CDataLine;
commandLine: StartCmd+ command ;
command
: halt
| note
| read
| end
;
halt : CHALT ;
end : CEND DataLine? ;
note : CNOTE DataLine? ;
read : CREAD fileName=StringLiteral ;
和词法分析器
lexer grammar T5Lexer ;
StartCmd: '@';
CDataLine: BOL ~'@' ~[\r\n]+;
EOL: EOL_F -> mode(DEFAULT_MODE);
WS: [ \t]+ -> channel(HIDDEN);
BOL : [\r\n\f]+ ;
DOT: [.];
COMMA: ',';
CHALT : 'HALT' ;
CEND : 'END' -> pushMode(DataMode);
CNOTE : 'NOTE' -> pushMode(DataMode);
CREAD : 'READ';
StringLiteral : DblQuotedString | SglQuotedString;
fragment DblQuotedString : [C]*'"' ( '\'. | '""' | ~('"'| '\') )* '"';
fragment SglQuotedString : [C]*'\'' ('\'. | '\'\'' | ~('\'' | '\'))* '\'';
fragment BackQuotedString : [C]*'`' ( '\'. | '``' | ~('`'|'\'))* '`';
//=======================================
mode DataMode ;
DmPOP : [ ,] -> popMode;
DmEOL: EOL_F -> type(EOL), popMode;
DataLine: ( ~[\r\n]*? '-' EOL_F)* ~[\r\n]+;
//=======================================
fragment NL: '\r'? '\n';
fragment EOL_F: [ ]* NL;
解析语法的以下方面工作正常
命令以@
开头命令可以有参数(这里以READ为例)或者可选 评论
不以@开头的行是“自由格式”内联数据 按原样消费
示例输入
@NOTE
@NOTE with data
@READ 'file.one'
Test data line
@END
@HALT
也许有更好的方法来匹配“行不以某物开头”,唉,这是我经过数小时的搜索所能想到的最好的方法,但是有了这个解决方案 我无法理解的方面是当“自由格式数据”出现在输入的第一行并且没有 BOL 时。
关于如何解决这个问题的任何提示?
TIA - 亚历克斯
像这样的东西就可以了:
lexer grammar T5Lexer;
CommandStart
: '@' -> mode(CommandMode)
;
DataLine
: ~[@\r\n] ~[\r\n]*
;
EOL
: [ \t]* ( '\r'? '\n' | '\r' )
;
mode CommandMode;
HALT : 'HALT' ;
END : 'END' -> mode(DEFAULT_MODE);
NOTE : 'NOTE' -> mode(DEFAULT_MODE);
READ : 'READ';
Spaces : [ \t]+ -> skip;
StringLiteral : '\'' ( '\'\'' | ~['\r\n] )* '\'';
CM_NewLine : EOL -> type(EOL), mode(DEFAULT_MODE);
使用语法分析器:
parser grammar T5Parser;
options {
tokenVocab=T5Lexer;
}
root
: line ( EOL+ line )* EOL* EOF
;
line
: commandLine
| DataLine
;
commandLine
: CommandStart command
;
command
: halt
| note
| read
| end
;
halt : HALT;
end : END DataLine?;
note : NOTE DataLine?;
read : READ StringLiteral;
这将解析输入:
first line
@NOTE
@NOTE with data
@READ 'file.one'
Test data line
@END
@HALT
像这样: