Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我可以让我的ANTLR4 Lexer从输入流中丢弃一个字符吗?_Antlr4 - Fatal编程技术网

我可以让我的ANTLR4 Lexer从输入流中丢弃一个字符吗?

我可以让我的ANTLR4 Lexer从输入流中丢弃一个字符吗?,antlr4,Antlr4,我正在解析PDF流。在关于文字字符串对象的第7.3.4.2节中,说明应忽略文字字符串中未后跟行尾字符、一到三个八进制数字或其中一个字符“nrtbf()\”的反斜杠。有没有办法让我的lexer中的recover方法在这种情况下忽略反斜杠 以下是我的简化解析器: parser grammar PdfStreamParser; options { tokenVocab=PdfSteamLexer; } array: LBRACKET object* RBRACKET ; dictionary:

我正在解析PDF流。在关于文字字符串对象的第7.3.4.2节中,说明应忽略文字字符串中未后跟行尾字符、一到三个八进制数字或其中一个字符“nrtbf()\”的反斜杠。有没有办法让我的lexer中的
recover
方法在这种情况下忽略反斜杠

以下是我的简化解析器:

parser grammar PdfStreamParser;

options { tokenVocab=PdfSteamLexer; } 

array: LBRACKET object* RBRACKET ;
dictionary: LDOUBLEANGLE (NAME object)* RDOUBLEANGLE ;
string: (LITERAL_STRING | HEX_STRING) ;
object
    : NULL
    | array
    | dictionary
    | BOOLEAN
    | NUMBER
    | string
    | NAME
    ;

content : stat* ;

stat
    : tj
    ;

tj: ((string Tj) | (array TJ)) ; // Show text
这是lexer。(根据《我不使用单独的字符串模式》中的建议):

lexer语法PdfStreamLexer;
Tj:‘Tj’;
TJ:‘TJ’;
空:“空”;
布尔值:('true'|'false');
勒布朗:“[”;
RBRACKET:']';
LDOUBLEANGLE:'';
编号:(“+”|“-”)?(国际浮点数);
名称:“/”ID;
//用括号括起来的一系列文字字符。
文字字符串:'('([()\\]+|转义序列|文字字符串)*');
//可以出现在文字字符串中的转义序列
片段逃逸序列
:“\\”([\r\nnrtbf()\\]\[0-7][0-7]?[0-7]?)
;
十六进制字符串:“”;//尖括号内的十六进制数据
片段INT:DIGIT+;//匹配一个或多个数字
片段浮点:数字+'.'数字*//匹配1。393.14159等。。。
|'.'位+//匹配.1.14159
;
片段数字:[0-9];//匹配一位数
//接受除空格和定义的分隔符以外的所有字符()[]{}/%
ID:~[\t\r\n\u000C\u0000()[\]{}/%]+;
WS:[\t\r\n\u000C\u0000]+->skip;//PDF定义了六个空白字符

我可以重写PdfStreamLexer类中的recover方法,并在出现
LexerNoViableAltException
时收到通知,但我不确定如何(或者如果可能的话)忽略反斜杠并继续进行文本字符串标记化。

要能够跳过部分字符串,需要使用词汇模式。下面是一个快速演示:

lexer grammar DemoLexer;

STRING_OPEN
 : '(' -> pushMode(STRING_MODE)
 ;

SPACES
 : [ \t\r\n] -> skip
 ;

OTHER
 : .
 ;

mode STRING_MODE;

  STRING_CLOSE
   : ')' -> popMode
   ;

  ESCAPE
   : '\\' ( [nrtbf()\\] | [0-7] [0-7] [0-7] )
   ;

  STRING_PART
   : ~[\\()]
   ;

  NESTED_STRING_OPEN
   : '(' -> type(STRING_OPEN), pushMode(STRING_MODE)
   ;

  IGNORED_ESCAPE
   : '\\' . -> skip
   ;
可在解析器中使用,如下所示:

parser grammar DemoParser;

options {
  tokenVocab=DemoLexer;
}

parse
 : ( string | OTHER )* EOF
 ;

string
 : STRING_OPEN ( ESCAPE | STRING_PART | string )* STRING_CLOSE
 ;
如果现在解析字符串
FU(abc(def)\@\)条
,将得到以下解析树:


如您所见,
\)
保留在树中,但忽略了
\@

也许您可以将转义序列视为“\\”后跟八进制序列或除“0”(由八进制处理)或行尾以外的任何字符。再次感谢。像解析器一样思考与像编译器一样思考有很大不同。我还有很长的路要走。我需要做的唯一更改是从忽略的转义中删除点,因为只有反斜杠被忽略,而不是它后面的字符。但是修改很好。啊,我明白了,只有
\@
中的反斜杠被省略,而
@
应该保留。那么是的,你是对的:
忽略\u转义:'\\'->跳过是一条路要走。当然不客气@SSteve
parser grammar DemoParser;

options {
  tokenVocab=DemoLexer;
}

parse
 : ( string | OTHER )* EOF
 ;

string
 : STRING_OPEN ( ESCAPE | STRING_PART | string )* STRING_CLOSE
 ;