sharp - try catch c#
¿Por qué la excepción.NET no es atrapada por try/catch block? (25)
Estoy trabajando en un proyecto que usa la biblioteca ANTLR parser para C #. Construí una gramática para analizar un texto y funciona bien. Sin embargo, cuando el analizador encuentra un token ilegal o inesperado, arroja una de muchas excepciones. El problema es que en algunos casos (no en todos) mi bloque try / catch no lo detecta y en su lugar detiene la ejecución como una excepción no controlada.
El problema para mí es que no puedo replicar este problema en ningún otro lado, sino en mi código completo. La pila de llamadas muestra que la excepción definitivamente ocurre dentro de mi bloque try / catch (Exception). Lo único que se me ocurre es que hay algunas llamadas ANTLR de ensamblaje que se producen entre mi código y el código que arroja la excepción y esta biblioteca no tiene habilitada la depuración, por lo que no puedo pasar por ella. Me pregunto si los ensamblajes no depurables inhiben el burbujeo de excepción. La pila de llamadas se ve así; las llamadas al ensamblado externo están en Antlr.Runtime:
Expl.Itinerary.dll!TimeDefLexer.mTokens() Line 1213 C# Antlr3.Runtime.dll!Antlr.Runtime.Lexer.NextToken() + 0xfc bytes Antlr3.Runtime.dll!Antlr.Runtime.CommonTokenStream.FillBuffer() + 0x22c bytes Antlr3.Runtime.dll!Antlr.Runtime.CommonTokenStream.LT(int k = 1) + 0x68 bytes Expl.Itinerary.dll!TimeDefParser.prog() Line 109 + 0x17 bytes C# Expl.Itinerary.dll!Expl.Itinerary.TDLParser.Parse(string Text = "", Expl.Itinerary.IItinerary Itinerary = {Expl.Itinerary.MemoryItinerary}) Line 17 + 0xa bytes C#
El fragmento de código de la llamada inferior en Parse () se ve así:
try {
// Execution stopped at parser.prog()
TimeDefParser.prog_return prog_ret = parser.prog();
return prog_ret == null ? null : prog_ret.value;
}
catch (Exception ex) {
throw new ParserException(ex.Message, ex);
}
Para mí, una cláusula catch (Exception) debería haber capturado cualquier excepción. ¿Hay alguna razón por la que no?
Actualización: rastreé el ensamblaje externo con Reflector y no encontré ninguna prueba de enhebrado. El ensamblado parece ser solo una clase de utilidad de tiempo de ejecución para el código generado por ANTLR. La excepción lanzada es del método TimeDefLexer.mTokens () y su tipo es NoViableAltException, que se deriva de RecognitionException -> Exception. Esta excepción se produce cuando el lexer no puede entender el siguiente token en la secuencia; en otras palabras, entrada inválida. Se supone que esta excepción sucederá, sin embargo, debería haber sido capturada por mi bloque try / catch.
Además, el reinicio de ParserException es realmente irrelevante para esta situación. Esa es una capa de abstracción que toma cualquier excepción durante el análisis sintáctico y convierte a mi propia ParserException. El problema de manejo de excepciones que estoy experimentando nunca llega a esa línea de código. De hecho, comenté la parte "throw new ParserException" y todavía recibí el mismo resultado.
Una cosa más, modifiqué el bloque try / catch original en cuestión para capturar NoViableAltException, eliminando cualquier confusión de herencia. Aún recibí el mismo resultado.
Alguien sugirió una vez que a veces VS es hiperactivo en la captura de excepciones manipuladas cuando está en modo de depuración, pero este problema también ocurre en el modo de lanzamiento.
Hombre, todavía estoy perplejo! No lo había mencionado antes, pero estoy ejecutando VS 2008 y todo mi código es 3.5. El ensamblaje externo es 2.0. Además, parte de mi código subclasifica una clase en el ensamblado 2.0. ¿Podría una versión no coincidente causar este problema?
Actualización 2: pude eliminar el conflicto de la versión de .NET trasladando partes relevantes de mi código .NET 3.5 a un proyecto .NET 2.0 y replicando el mismo escenario. Pude replicar la misma excepción no controlada cuando se ejecuta de forma coherente en .NET 2.0.
Me enteré de que ANTLR lanzó recientemente 3.1. Entonces, actualicé desde 3.0.1 y reintenté. Resulta que el código generado se refactoriza un poco, pero la misma excepción no controlada se produce en mis casos de prueba.
Actualización 3: he replicado este escenario en un proyecto VS 2008 simplificado . No dude en descargar e inspeccionar el proyecto usted mismo. Apliqué todas las grandes sugerencias, pero aún no he podido superar este obstáculo.
Si puede encontrar una solución, por favor comparta sus hallazgos. ¡Gracias de nuevo!
Gracias, pero VS 2008 automáticamente se rompe con las excepciones no controladas. Además, no tengo un diálogo de Depuración-> Excepciones. La excepción NoViableAltException que se lanza está completamente diseñada y diseñada para ser capturada por el código de usuario. Como no se captura como se esperaba, la ejecución del programa se detiene inesperadamente como una excepción no controlada.
La excepción lanzada se deriva de Exception y no hay multi-threading con ANTLR.
"Además, puede poner un código para capturar todas las excepciones no controladas. Lea el enlace para obtener más información, pero los conceptos básicos son estas dos líneas".
Esto es falso Esto solía detectar todas las excepciones no controladas en .NET 1.0 / 1.1, pero era un error y no se suponía que así fuera, y se corrigió en .NET 2.0.
AppDomain.CurrentDomain.UnhandledException
Solo está pensado para ser utilizado como último salón de registro de oportunidades para que pueda registrar la excepción antes de que el programa finalice. No captará la excepción desde 2.0 en adelante (aunque en .NET 2.0 al menos hay un valor de configuración que puede modificar para que actúe como 1.1, pero no se recomienda practicarlo).
Vale la pena señalar que hay pocas excepciones que no se pueden detectar, como Exception y OutOfMemoryException. De lo contrario, como otras personas han sugerido que podría ser una excepción en un hilo de fondo en alguna parte. También estoy bastante seguro de que no puedes capturar algunas / todas las excepciones no administradas / nativas tampoco.
Para mí, una cláusula catch (Exception) debería haber capturado cualquier excepción. ¿Hay alguna razón por la que no?
La única posibilidad en la que puedo pensar es que algo más está atrapándola frente a usted y manejándola de una manera que parece ser una excepción no detectada (por ejemplo, salir del proceso).
mi bloque try / catch no lo detectará y en su lugar detiene la ejecución como una excepción no controlada.
Necesita encontrar lo que está causando el proceso de salida. Puede ser algo más que una excepción no controlada. Puede intentar usar el depurador nativo con un conjunto de puntos de interrupción en "{,, kernel32.dll} ExitProcess". Luego use SOS para determinar qué código administrado está llamando al proceso de salida.
Remonté el ensamblaje externo con Reflector y no encontré ninguna prueba de enhebrar nada.
No puede encontrar ningún subproceso que no signifique que no hay subprocesos
.NET tiene un ''grupo de subprocesos'', que es un conjunto de subprocesos ''libres'' que permanecen prácticamente inactivos. Ciertos métodos hacen que las cosas se ejecuten en uno de los subprocesos del grupo de subprocesos para que no bloqueen su aplicación principal.
Los ejemplos evidentes son cosas como ThreadPool.QueueUserWorkItem , pero hay muchas otras cosas que también pueden ejecutar cosas en el grupo de subprocesos que no se ven tan obvias, como Delegate.BeginInvoke
Realmente, necesitas hacer lo que sugiere kibbee .
¿Es posible que la excepción sea lanzada en otro hilo? Obviamente, su código de llamada es de un solo hilo, pero tal vez la biblioteca que está consumiendo está haciendo algunas operaciones multiproceso bajo las sábanas.
¿Estás usando .Net 1.0 o 1.1? Si es así, catch (Exception ex) no detectará excepciones del código no administrado. Deberás usar catch {} en su lugar. Vea este artículo para más detalles:
http://www.netfxharmonics.com/2005/10/net-20-trycatch-and-trycatchexception/
¿Ha intentado imprimir (Console.WriteLine ()) la excepción dentro de la cláusula catch, y no usar visual studio y ejecutar su aplicación en la consola?
@spoulson,
Si puedes replicarlo, ¿puedes publicarlo en alguna parte? Una forma de intentarlo es utilizar WinDBG con las extensiones SOS para ejecutar la aplicación y atrapar la excepción no controlada. Se romperá con la excepción de la primera oportunidad (antes de que el tiempo de ejecución intente encontrar un controlador) y podrá ver en qué punto proviene y qué hilo.
Si no ha usado WinDBG anteriormente, puede ser un poco abrumador, pero este es un buen tutorial:
Una vez que inicie WinDBG, puede alternar el rompimiento de las excepciones no controladas yendo a Depurar-> Filtros de eventos.
Ah, y en referencia a lo que dijo Kibbee; si selecciona Debug | Exceptions en VS y simplemente hace clic en todos los cuadros en la columna ''throw'', debe recoger todo AFAIK como una ''excepción de primera oportunidad'', es decir, VS indicará cuándo la excepción va a ser procesada por todo lo demás y romper el código relevante. Esto debería ayudar con la depuración.
Creo que Steve Steiner está en lo cierto. Al investigar las sugerencias de Steve, encontré este hilo hablando de la opción "Habilitar mi código" en Herramientas | Opciones | Depurador | General. Se sugiere que el depurador se rompa en ciertas condiciones cuando el código no del usuario arroja o maneja una excepción. No estoy exactamente seguro de por qué esto importa, o por qué el depurador dice específicamente que la excepción no fue controlada cuando realmente era.
Pude eliminar los saltos falsos desactivando la opción "Habilitar solo mi código". Esto también cambia el diálogo de Depuración | Excepciones al eliminar la columna "Manejado por el usuario" ya que no se aplica. O bien, puede desmarcar el cuadro "Manejado por el usuario" para CLR y obtener el mismo resultado.
Bigtime gracias por ayudar a todos!
Creo que entiendo el problema. Se está capturando la excepción, el problema es la confusión sobre el comportamiento del depurador y las diferencias en la configuración del depurador entre cada persona que intenta reproducir.
En el tercer caso de su repro, creo que está recibiendo el siguiente mensaje: "NoViableAltException no fue manejado por el código de usuario" y una pila de llamadas que se ve así:
[External Code] > TestAntlr-3.1.exe!TimeDefLexer.mTokens() Line 852 + 0xe bytes C# [External Code] TestAntlr-3.1.exe!TimeDefParser.prog() Line 141 + 0x14 bytes C# TestAntlr-3.1.exe!TestAntlr_3._1.Program.ParseTest(string Text = "foobar;") Line 49 + 0x9 bytes C# TestAntlr-3.1.exe!TestAntlr_3._1.Program.Main(string[] args = {string[0x00000000]}) Line 30 + 0xb bytes C# [External Code]
Si haces clic con el botón derecho en la ventana de la pila de llamadas y ejecutas encender el código externo, ves esto:
Antlr3.Runtime.dll!Antlr.Runtime.DFA.NoViableAlt(int s = 0x00000000, Antlr.Runtime.IIntStream input = {Antlr.Runtime.ANTLRStringStream}) + 0x80 bytes Antlr3.Runtime.dll!Antlr.Runtime.DFA.Predict(Antlr.Runtime.IIntStream input = {Antlr.Runtime.ANTLRStringStream}) + 0x21e bytes > TestAntlr-3.1.exe!TimeDefLexer.mTokens() Line 852 + 0xe bytes C# Antlr3.Runtime.dll!Antlr.Runtime.Lexer.NextToken() + 0xc4 bytes Antlr3.Runtime.dll!Antlr.Runtime.CommonTokenStream.FillBuffer() + 0x147 bytes Antlr3.Runtime.dll!Antlr.Runtime.CommonTokenStream.LT(int k = 0x00000001) + 0x2d bytes TestAntlr-3.1.exe!TimeDefParser.prog() Line 141 + 0x14 bytes C# TestAntlr-3.1.exe!TestAntlr_3._1.Program.ParseTest(string Text = "foobar;") Line 49 + 0x9 bytes C# TestAntlr-3.1.exe!TestAntlr_3._1.Program.Main(string[] args = {string[0x00000000]}) Line 30 + 0xb bytes C# [Native to Managed Transition] [Managed to Native Transition] mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args) + 0x39 bytes Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x2b bytes mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x3b bytes mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x81 bytes mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x40 bytes
El mensaje del depurador le dice que una excepción que se origina fuera de su código (de NoViableAlt) está pasando por el código que posee en TestAntlr-3.1.exe! TimeDefLexer.mTokens () sin ser manejado.
La redacción es confusa, pero no significa que la excepción no haya sido detectada. El depurador le informa que el código que posee mTokens () "necesita ser robusto para evitar que se produzca esta excepción.
Cosas con las que jugar para ver cómo se ve esto para los que no reprodujeron el problema:
- Vaya a Herramientas / Opciones / Depuración y desactive "Habilitar solo mi código (solo administrado)". u opción.
- Vaya a Depurador / Excepciones y desactive "Usuario no controlado" para las excepciones de Common-Language Runtime.
Descargué el proyecto de muestra VS2008, y estoy un poco perplejo aquí también. Sin embargo, pude superar las excepciones, aunque probablemente de una manera que no funcionará será genial para usted. Pero esto es lo que encontré:
Esta publicación de la lista de correo tuvo una discusión sobre lo que parece ser el mismo problema que estás experimentando.
A partir de ahí, agregué un par de clases ficticias en el archivo principal program.cs:
class MyNoViableAltException : Exception
{
public MyNoViableAltException()
{
}
public MyNoViableAltException(string grammarDecisionDescription, int decisionNumber, int stateNumber, Antlr.Runtime.IIntStream input)
{
}
}
class MyEarlyExitException : Exception
{
public MyEarlyExitException()
{
}
public MyEarlyExitException(int decisionNumber, Antlr.Runtime.IIntStream input)
{
}
}
y luego agregó las líneas usando TimeDefParser.cs y TimeDefLexer.cs:
using NoViableAltException = MyNoViableAltException;
using EarlyExitException = NoViableAltException;
Con eso, las excepciones se convertirían en las clases de excepciones falsas y podrían manejarse allí, pero todavía se lanzaba una excepción en el método mTokens en TimeDefLexer.cs. Envolver eso en una captura de prueba en esa clase captó la excepción:
try
{
alt4 = dfa4.Predict(input);
}
catch
{
}
Realmente no entiendo por qué envolverlo en el método interno en lugar de llamarlo desde el error si el enhebrado no está en juego, pero de todos modos con suerte eso señalará a alguien más inteligente que yo aquí en la dirección correcta.
Descargué tu código y todo funcionó como esperaba.
El depurador de Visual Studio intercepta correctamente todas las excepciones. Los bloques de captura funcionan como se esperaba.
Estoy ejecutando Windows 2003 servidor SP2, VS2008 Team Suite (9.0.30729.1 SP)
Intenté compilar tu proyecto para .NET 2.0, 3.0 y 3.5
@Steve Steiner, las opciones de depuración que mencionó no tienen nada que ver con este comportamiento.
Traté de jugar con estas opciones sin efectos visibles: atrapar bloques logró interceptar todas las excepciones.
Estoy con @Shaun Austin: prueba el intento con el nombre completo
catch (System.Exception)
y ver si eso ayuda. ¿El documento ANTLR dice qué excepciones deberían arrojarse?
Estoy de acuerdo con y kronoz que esto huele a una excepción que tiene algo que ver con los hilos. Más allá de eso, aquí están mis otras preguntas:
- ¿Qué dice el mensaje de error completo? ¿Qué tipo de excepción es?
- Según el seguimiento de la pila que proporcionó aquí, ¿no es la excepción lanzada por su código en TimeDefLexer.mTokens ()?
Hmm, no entiendo el problema. Descargué y probé su archivo de solución de ejemplo.
Se lanza una excepción en TimeDefLexer.cs, línea 852, que posteriormente es manejada por el bloque catch en Program.cs que solo dice Excepción manejada.
Si elimino el comentario del bloque catch encima de él, ingresará ese bloque en su lugar.
Qué es lo que parece ser el problema aquí?
Como dijo Kibbee, Visual Studio se detendrá con excepciones, pero si le pide que continúe, la excepción quedará atrapada por su código.
Independientemente de si el ensamblado se ha compilado como una versión de lanzamiento, la excepción ciertamente debe ''burbujear'' hasta la persona que llama, no hay razón para que un ensamblado que no se compila en modo de depuración tenga algún efecto sobre eso.
Estoy de acuerdo con que Daniel sugiere que tal vez la excepción se está produciendo en un hilo separado: intente conectar el evento de excepción de subproceso en Application.ThreadException. Esto debería plantearse cuando se produce una excepción de subproceso no administrado. Podrías adaptar tu código así:
using System.Threading;
...
void Application_ThreadException(object sender, ThreadExceptionEventArgs e) {
throw new ParserException(e.Exception.Message, e.Exception);
}
...
var exceptionHandler =
new ThreadExceptionEventHandler(Application_ThreadException);
Application.ThreadException += exceptionHandler;
try {
// Execution stopped at parser.prog()
TimeDefParser.prog_return prog_ret = parser.prog();
return prog_ret == null ? null : prog_ret.value;
}
catch (Exception ex) {
throw new ParserException(ex.Message, ex);
}
finally {
Application.ThreadException -= exceptionHandler;
}
La mejor opción suena como configurar Visual Studio para romper todas las excepciones no controladas (Depurar -> diálogo de Excepciones, marcar la casilla de "Excepciones de Common Language Runtime" y posiblemente las otras también). Luego ejecuta tu programa en modo de depuración. Cuando el código del analizador ANTLR arroja una excepción, debe ser capturado por Visual Studio y le permite ver dónde está ocurriendo, el tipo de excepción, etc.
Según la descripción, el bloque catch parece ser correcto, por lo que podría estar ocurriendo una de varias cosas:
- el analizador no está lanzando una excepción
- el analizador finalmente está lanzando algo que no se deriva de System.Exception
- hay una excepción lanzada en otro hilo que no se está manejando
Parece que posiblemente descartó el problema n. ° 3.
No estoy seguro de si no estoy seguro, pero si es así, veo que el depurador detiene la ejecución con una "Excepción no controlada" de tipo NoViableAltException. Inicialmente, no sabía nada sobre este elemento del menú Depurar-> Excepciones porque MS espera que, en el momento de la instalación de VS, se comprometa con un perfil cuando no tenga idea de cómo son diferentes. Aparentemente, no estaba en el perfil dev de C # y me faltaba esta opción . Después de depurar finalmente todas las excepciones de CLR lanzadas, desafortunadamente no pude descubrir ningún comportamiento nuevo que conduzca a la razón de este problema de excepción no controlada. Todas las excepciones arrojadas se esperaban y supuestamente se manejaban en un bloque try / catch.
Revisé el ensamblaje externo y no hay evidencia de multihilo. Con eso, quiero decir que no existe ninguna referencia a System.Threading y no se usaron delegados en absoluto. Estoy familiarizado con eso constituye una instancia de un hilo. Verifico esto al observar la caja de herramientas Threads en el momento de la excepción no controlada para ver que solo hay un hilo en ejecución.
Tengo un problema abierto con la gente ANTLR así que tal vez hayan podido abordar este problema antes. Pude replicarlo en un simple proyecto de aplicación de consola usando .NET 2.0 y 3.5 en VS 2008 y VS 2005.
Es solo un punto doloroso porque obliga a mi código a funcionar solo con la entrada del analizador válido conocido. Usar un método IsValid()
sería arriesgado si lanzara una excepción no controlada en función de la entrada del usuario. Mantendré esta pregunta actualizada cuando se aprenda más sobre este tema.
No lo entiendo ... tu bloque catch simplemente arroja una nueva excepción (con el mismo mensaje). Lo que significa que su declaración de:
El problema es que en algunos casos (no en todos) mi bloque try / catch no lo detecta y en su lugar detiene la ejecución como una excepción no controlada.
es exactamente lo que se espera que suceda
Personalmente, no estoy convencido por la teoría de subprocesos en absoluto.
La única vez que he visto esto antes, estaba trabajando con una biblioteca que también definía Exception y los usos que había querido decir de que la Captura real se refería a un tipo de "Excepción" diferente (si hubiera sido totalmente calificado, era Compañía). Lib.Exception pero no fue por el uso) así que cuando se trataba de capturar una excepción normal que se estaba lanzando (algún tipo de excepción de argumento si mal no recuerdo) simplemente no la captaba porque el tipo no coincidía.
Entonces, en resumen, ¿hay otro tipo de excepción en un espacio de nombres diferente que esté en uso en esa clase?
EDITAR: ¡Una forma rápida de verificar esto es asegurarse de que en su cláusula catch califique completamente el tipo de Excepción como "System.Exception" y le dé un giro!
EDIT2: OK He intentado con el código y reconozco la derrota por ahora. Tendré que echarle otro vistazo por la mañana si nadie ha encontrado una solución.
Puede configurar VS.Net para romper tan pronto como ocurra una excepción. Simplemente ejecute su proyecto en modo de depuración, y se detendrá tan pronto como se produzca la excepción. Entonces deberías tener una mejor idea de por qué no está siendo atrapado.
Además, puede poner algún código para atrapar todas las excepciones no controladas . Lea el enlace para obtener más información, pero los conceptos básicos son estas dos líneas.
Application.ThreadException += new ThreadExceptionEventHandler(ThreadExceptionHandler);
// Catch all unhandled exceptions in all threads.
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
Puedo decirte lo que está pasando aquí ...
Visual Studio se está rompiendo porque cree que la excepción no se ha controlado. ¿Qué significa "no manejado"? Bueno, en Visual Studio, hay una configuración en Herramientas ... Opciones ... Depuración ... General ... "Habilitar solo mi código (solo administrado)". Si esto está marcado y si la excepción se propaga fuera de su código y sale a un marco de pila asociado con una llamada a método que existe en un ensamblaje que "NO ES SU CÓDIGO" (por ejemplo, Antlr), se considera "no controlado". Apago la función Habilitar mi código simplemente por este motivo. Pero, si me preguntas, esto es cojo ... digamos que haces esto:
ExternalClassNotMyCode c = new ExternalClassNotMyCode();
try {
c.doSomething( () => { throw new Exception(); } );
}
catch ( Exception ex ) {}
doSomething llama a su función anónima allí y esa función arroja una excepción ...
Tenga en cuenta que esta es una "excepción no controlada" de acuerdo con Visual Studio si está habilitada "Habilitar solo mi código". Además, tenga en cuenta que se detiene como si fuera un punto de interrupción cuando está en modo de depuración, pero en un entorno de depuración o producción, el código es perfectamente válido y funciona como se esperaba. Además, si simplemente "continúa" en el depurador, la aplicación continúa de forma feliz (no detiene el hilo). Se considera "no controlado" porque la excepción se propaga a través de un marco de pila que NO está en su código (es decir, en la biblioteca externa). Si me preguntas, esto es pésimo. Por favor cambie este comportamiento predeterminado Microsoft. Este es un caso perfectamente válido de usar Excepciones para controlar la lógica del programa. A veces, no puede cambiar la biblioteca de terceros para comportarse de otra manera, y esta es una forma muy útil de realizar muchas tareas.
Tome MyBatis, por ejemplo, puede usar esta técnica para detener el procesamiento de registros que se están recopilando mediante una llamada a SqlMapper.QueryWithRowDelegate.
Si está utilizando objetos com en su proyecto y prueba atrapar bloques que no detectan las excepciones, deberá deshabilitar Herramientas / Depuración / Descanso cuando las excepciones se crucen con las opciones AppDomain o con límites administrados / nativos (solo administrados).
Steve Steiner tiene razón en que la excepción se origina en la biblioteca antlr, pasa a través del método mTokens () y queda atrapada en la biblioteca antlr. El problema es que este método es generado automáticamente por antlr. Por lo tanto, cualquier cambio para manejar la excepción en mTokens () se sobrescribirá cuando genere sus clases de analizador / lexer.
De forma predeterminada, antlr registrará los errores y tratará de recuperar el análisis sintáctico. Puede anular esto para que parser.prog () arroje una excepción cada vez que se encuentre un error. De su código de ejemplo, creo que este es el comportamiento que esperaba.
Agregue este código a su archivo grammer (.g). También deberá desactivar "Habilitar solo mi código" en el menú de depuración.
@members {
public override Object RecoverFromMismatchedSet(IIntStream input,RecognitionException e, BitSet follow)
{
throw e;
}
}
@rulecatch {
catch (RecognitionException e)
{
throw e;
}
}
Este es mi intento de una versión C # del ejemplo dado en el capítulo "Salir del reconocedor en el primer error" del libro "Referencia definitiva ANTLR".
Espero que esto sea lo que estabas buscando.
Vaya, de los informes hasta ahora, 2 funcionaron correctamente y 1 experimenté el problema que reporté. ¿Cuáles son las versiones de Windows, Visual Studio utilizadas y .NET framework con números de compilación?
Estoy ejecutando XP SP2, VS 2008 Team Suite (9.0.30729.1 SP), C # 2008 (91899-270-92311015-60837) y .NET 3.5 SP1.