ANTLR异常 - “无法将索引111处的Unicode字符\ uDCAF转换为指定的代码页。”

时间:2011-08-08 17:48:14

标签: .net iis-7 unicode antlr antlr3

致电所有ANTLR专家!

我在IIS网站上托管了一个.NET程序集,它使用ANTLR进行自然语言查询处理,搜索引擎样式。例如,如果用户键入:

奶酪和饼干而不是薯条

它构建以下语句:

AND(AND(“cheese”,“crackers”),NOT(“筹码”))

然后我们将该声明发送到我们的内容存储库并向用户提供一些内容。 99.9%的时间一切都很好。但是,每隔一段时间,ANTLR就会出现问题,执行此处理的IIS托管站点会陷入某种错误状态,并且在我们执行IISReset / AppPool循环之前不停地抛出错误。回收后,错误立即停止。

我正在捕获这些错误的堆栈跟踪,我在下面列出了(根据公司政策进行了清理):

System.Text.EncoderFallbackException: Unable to translate Unicode character \uDCAF at index 111 to specified code page.
 at System.Text.EncoderExceptionFallbackBuffer.Fallback(Char charUnknown, Int32 index)
 at System.Text.EncoderFallbackBuffer.InternalFallback(Char ch, Char*& chars)
 at System.Text.UTF8Encoding.GetBytes(Char* chars, Int32 charCount, Byte* bytes, Int32 byteCount, EncoderNLS baseEncoder)
 at System.Text.EncoderNLS.GetBytes(Char* chars, Int32 charCount, Byte* bytes, Int32 byteCount, Boolean flush)
 at System.Text.EncoderNLS.GetBytes(Char[] chars, Int32 charIndex, Int32 charCount, Byte[] bytes, Int32 byteIndex, Boolean flush)
 at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder)
 at System.IO.StreamWriter.Write(Char[] buffer, Int32 index, Int32 count)
 at System.IO.TextWriter.WriteLine(String value)
 at System.IO.TextWriter.SyncTextWriter.WriteLine(String value)
 at Antlr.Runtime.BaseRecognizer.EmitErrorMessage(String msg)
 at Service123.Parser.atomicExpression() in Parser.cs:line 927
 at Service123.Parser.notExpression() in Parser.cs:line 657
 at Service123.Parser.orExpression() in Parser.cs:line 516
 at Service123.Parser.andnotExpression() in Parser.cs:line 416
 at Service123.Parser.andExpression() in Parser.cs:line 234
 at Service123.Parser.startExpression() in Parser.cs:line 167
 at Service123.Processor.ProcessQuery(String queryString) in Processor.cs:line 34
 at Service123.Search.ProcessQueryString(String query) in Search.cs:line 1017

以下是我的语法文件的副本(根据公司政策再次清理):

grammar Parser;

options { language = CSharp2; output = AST; }

tokens { IMPLICIT_AND; }

@lexer::namespace { Service123.Parser }
@parser::namespace { Service123.Parser }

L_PARENTHESIS : '(';
R_PARENTHESIS : ')';

AND    : ('A'|'a')('N'|'n')('D'|'d');
OR     : ('O'|'o')('R'|'r');
ANDNOT : ('A'|'a')('N'|'n')('D'|'d')('N'|'n')('O'|'o')('T'|'t');
NOT    : ('N'|'n')('O'|'o')('T'|'t');

fragment LETTER        : ('a'..'z'|'A'..'Z');
fragment NUMBER        : ('0'..'9');
fragment SYMBOL_1      : ('+'|'-'|'_'|'|'|'~'|'&'|'`'|'='|'['|']'|'{'|'}');
fragment SYMBOL_2      : ('!'|'@'|'#'|'$'|'%'|'^'|'*'|','|'.'|'/'|':'|';'|'<'|'>'|'?'|'\''|'\\');
fragment SYMBOL_QUOTE  : ('"');
fragment SPACE         : (' '|'\n'|'\r'|'\t'|'\u000C');

WS     : (SPACE) { $channel=HIDDEN; };
PHRASE : (SYMBOL_QUOTE)(LETTER|NUMBER|SYMBOL_1|SYMBOL_2)+((SPACE)+(LETTER|NUMBER|SYMBOL_1|SYMBOL_2)+)+(SYMBOL_QUOTE);
WORD   : (LETTER|NUMBER|SYMBOL_1)+;

startExpression  : andExpression;
andExpression    : (         andnotExpression ->              andnotExpression    )
                   (AND? e = andnotExpression -> ^(IMPLICIT_AND $andExpression $e))*;
andnotExpression : orExpression (ANDNOT^ orExpression)*;
orExpression     : notExpression (OR^ notExpression)*;
notExpression    : (NOT^)? atomicExpression;
atomicExpression : PHRASE | WORD | L_PARENTHESIS! andExpression R_PARENTHESIS!;

我还记录了与这些错误一起出现的查询字符串,它们似乎是普通的,普通的英语搜索术语。

关于错误,所讨论的代码点并不总是\ uDCAF,而是在整个错误周期内保持一致;在我们退回服务之前,它始终是相同的代码点,然后当一周的工作正常后错误再次出现时,它会有所不同。

我能够记录的所有代码点都是代理对的一部分,并不代表有效的字形。

我是一名入院的ANTLR新手,并且对其内部工作知识不足以进一步诊断。在我看来,ANTLR运行时中有一个单例以某种方式搞砸了,并且在我们重新加载程序集之前,所有进一步的处理都没用。但是,我没有这方面的证据。

如果您需要更多详细信息或说明,请不要犹豫,因为我的机智已经结束了。

0 个答案:

没有答案