PR #1658: Also write stderr to file

This commit is contained in:
Ben Hamilton 2017-02-16 09:19:02 -08:00
parent 6c878b0709
commit c35bbabc16
10 changed files with 77 additions and 56 deletions

View File

@ -14,6 +14,7 @@ import org.antlr.v4.runtime.misc.Utils;
import org.antlr.v4.test.runtime.ErrorQueue;
import org.antlr.v4.test.runtime.RuntimeTestSupport;
import org.antlr.v4.test.runtime.StreamVacuum;
import org.antlr.v4.test.runtime.TestOutputReading;
import org.antlr.v4.tool.ANTLRMessage;
import org.antlr.v4.tool.GrammarSemanticsMessage;
import org.junit.rules.TestRule;
@ -39,6 +40,7 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@ -241,7 +243,7 @@ public class BaseCSharpTest implements RuntimeTestSupport /*, SpecialRuntimeTest
return stderrDuringParse;
}
String output = execTest();
if ( output.length()==0 ) {
if ( output!=null && output.length()==0 ) {
output = null;
}
return output;
@ -489,26 +491,18 @@ public class BaseCSharpTest implements RuntimeTestSupport /*, SpecialRuntimeTest
public String execTest() {
String exec = locateExec();
String[] args = getExecTestArgs(exec);
try {
File tmpdirFile = new File(tmpdir);
Path output = tmpdirFile.toPath().resolve("output");
Path errorOutput = tmpdirFile.toPath().resolve("error-output");
String[] args = getExecTestArgs(exec, output, errorOutput);
ProcessBuilder pb = new ProcessBuilder(args);
pb.directory(new File(tmpdir));
pb.directory(tmpdirFile);
Process process = pb.start();
StreamVacuum stdoutVacuum = new StreamVacuum(process.getInputStream());
StreamVacuum stderrVacuum = new StreamVacuum(process.getErrorStream());
stdoutVacuum.start();
stderrVacuum.start();
process.waitFor();
stdoutVacuum.join();
stderrVacuum.join();
String output = stdoutVacuum.toString();
if ( output.length()==0 ) {
output = null;
}
if ( stderrVacuum.toString().length()>0 ) {
this.stderrDuringParse = stderrVacuum.toString();
}
return output;
String writtenOutput = TestOutputReading.read(output);
this.stderrDuringParse = TestOutputReading.read(errorOutput);
return writtenOutput;
}
catch (Exception e) {
System.err.println("can't exec recognizer");
@ -517,12 +511,12 @@ public class BaseCSharpTest implements RuntimeTestSupport /*, SpecialRuntimeTest
return null;
}
private String[] getExecTestArgs(String exec) {
private String[] getExecTestArgs(String exec, Path output, Path errorOutput) {
if(isWindows())
return new String[] { exec, new File(tmpdir, "input").getAbsolutePath() } ;
return new String[] { exec, new File(tmpdir, "input").getAbsolutePath(), output.toAbsolutePath().toString(), errorOutput.toAbsolutePath().toString() } ;
else {
String mono = locateTool("mono");
return new String[] { mono, exec, new File(tmpdir, "input").getAbsolutePath() };
return new String[] { mono, exec, new File(tmpdir, "input").getAbsolutePath(), output.toAbsolutePath().toString(), errorOutput.toAbsolutePath().toString() };
}
}
@ -591,16 +585,23 @@ public class BaseCSharpTest implements RuntimeTestSupport /*, SpecialRuntimeTest
"using System;\n" +
"using Antlr4.Runtime;\n" +
"using Antlr4.Runtime.Tree;\n" +
"using System.IO;\n" +
"using System.Text;\n" +
"\n" +
"public class Test {\n" +
" public static void Main(string[] args) {\n" +
" ICharStream input = new AntlrFileStream(args[0]);\n" +
" <lexerName> lex = new <lexerName>(input);\n" +
" CommonTokenStream tokens = new CommonTokenStream(lex);\n" +
" <createParser>\n"+
" parser.BuildParseTree = true;\n" +
" ParserRuleContext tree = parser.<parserStartRuleName>();\n" +
" ParseTreeWalker.Default.Walk(new TreeShapeListener(), tree);\n" +
" string inputData = File.ReadAllText(args[0], Encoding.UTF8);\n" +
" using (TextWriter output = new StreamWriter(args[1]),\n" +
" errorOutput = new StreamWriter(args[2])) {\n" +
" CodePointCharStream input = new CodePointCharStream(inputData);\n" +
" input.name = args[0];\n" +
" <lexerName> lex = new <lexerName>(input, output, errorOutput);\n" +
" CommonTokenStream tokens = new CommonTokenStream(lex);\n" +
" <createParser>\n"+
" parser.BuildParseTree = true;\n" +
" ParserRuleContext tree = parser.<parserStartRuleName>();\n" +
" ParseTreeWalker.Default.Walk(new TreeShapeListener(), tree);\n" +
" }\n" +
" }\n" +
"}\n" +
"\n" +
@ -619,11 +620,11 @@ public class BaseCSharpTest implements RuntimeTestSupport /*, SpecialRuntimeTest
" }\n" +
"}"
);
ST createParserST = new ST(" <parserName> parser = new <parserName>(tokens);\n");
ST createParserST = new ST(" <parserName> parser = new <parserName>(tokens, output, errorOutput);\n");
if ( debug ) {
createParserST =
new ST(
" <parserName> parser = new <parserName>(tokens);\n" +
" <parserName> parser = new <parserName>(tokens, output, errorOutput);\n" +
" parser.AddErrorListener(new DiagnosticErrorListener());\n");
}
outputFileST.add("createParser", createParserST);
@ -637,17 +638,23 @@ public class BaseCSharpTest implements RuntimeTestSupport /*, SpecialRuntimeTest
ST outputFileST = new ST(
"using System;\n" +
"using Antlr4.Runtime;\n" +
"using System.IO;\n" +
"using System.Text;\n" +
"\n" +
"public class Test {\n" +
" public static void Main(string[] args) {\n" +
" ICharStream input = new AntlrFileStream(args[0]);\n" +
" <lexerName> lex = new <lexerName>(input);\n" +
" CommonTokenStream tokens = new CommonTokenStream(lex);\n" +
" tokens.Fill();\n" +
" foreach (object t in tokens.GetTokens())\n" +
" Console.WriteLine(t);\n" +
(showDFA?" Console.Write(lex.Interpreter.GetDFA(Lexer.DEFAULT_MODE).ToLexerString());\n":"")+
" }\n" +
" string inputData = File.ReadAllText(args[0], Encoding.UTF8);\n" +
" ICharStream input = new CodePointCharStream(inputData);\n" +
" using (TextWriter output = new StreamWriter(args[1]),\n" +
" errorOutput = new StreamWriter(args[2])) {\n" +
" <lexerName> lex = new <lexerName>(input, output, errorOutput);\n" +
" CommonTokenStream tokens = new CommonTokenStream(lex);\n" +
" tokens.Fill();\n" +
" foreach (object t in tokens.GetTokens())\n" +
" output.WriteLine(t);\n" +
(showDFA?" output.Write(lex.Interpreter.GetDFA(Lexer.DEFAULT_MODE).ToLexerString());\n":"")+
" }\n" +
"}\n" +
"}"
);

View File

@ -6,6 +6,7 @@ using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Sharpen;
using System.IO;
namespace Antlr4.Runtime
{
@ -19,7 +20,7 @@ namespace Antlr4.Runtime
/// <author>Sam Harwell</author>
public class BaseErrorListener : IParserErrorListener
{
public virtual void SyntaxError(IRecognizer recognizer, IToken offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e)
public virtual void SyntaxError(TextWriter output, IRecognizer recognizer, IToken offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e)
{
}

View File

@ -7,6 +7,7 @@
using Antlr4.Runtime;
using Antlr4.Runtime.Sharpen;
using System.IO;
namespace Antlr4.Runtime
{
@ -38,9 +39,9 @@ namespace Antlr4.Runtime
/// line <em>line</em>:<em>charPositionInLine</em> <em>msg</em>
/// </pre>
/// </summary>
public virtual void SyntaxError(IRecognizer recognizer, Symbol offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e)
public virtual void SyntaxError(TextWriter output, IRecognizer recognizer, Symbol offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e)
{
System.Console.Error.WriteLine("line " + line + ":" + charPositionInLine + " " + msg);
output.WriteLine("line " + line + ":" + charPositionInLine + " " + msg);
}
}
}

View File

@ -4,6 +4,7 @@
*/
using Antlr4.Runtime;
using Antlr4.Runtime.Sharpen;
using System.IO;
namespace Antlr4.Runtime
{
@ -30,6 +31,9 @@ namespace Antlr4.Runtime
/// in-line, without returning from the surrounding rule (via the single
/// token insertion and deletion mechanism).</p>
/// </remarks>
/// <param name="output">
/// Where the error should be written.
/// </param>
/// <param name="recognizer">
/// What parser got the error. From this
/// object, you can access the context as well
@ -52,6 +56,6 @@ namespace Antlr4.Runtime
/// the parser was able to recover in line without exiting the
/// surrounding rule.
/// </param>
void SyntaxError(IRecognizer recognizer, TSymbol offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e);
void SyntaxError(TextWriter output, IRecognizer recognizer, TSymbol offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e);
}
}

View File

@ -5,6 +5,7 @@
using Antlr4.Runtime;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
using System.IO;
namespace Antlr4.Runtime
{

View File

@ -36,6 +36,8 @@ namespace Antlr4.Runtime
protected readonly TextWriter Output;
protected readonly TextWriter ErrorOutput;
private Tuple<ITokenSource, ICharStream> _tokenFactorySourcePair;
/// <summary>How to create token objects</summary>
@ -97,12 +99,13 @@ namespace Antlr4.Runtime
/// </remarks>
private string _text;
public Lexer(ICharStream input) : this(input, Console.Out) { }
public Lexer(ICharStream input) : this(input, Console.Out, Console.Error) { }
public Lexer(ICharStream input, TextWriter output)
public Lexer(ICharStream input, TextWriter output, TextWriter errorOutput)
{
this._input = input;
this.Output = output;
this.ErrorOutput = errorOutput;
this._tokenFactorySourcePair = Tuple.Create((ITokenSource)this, input);
}
@ -555,7 +558,7 @@ outer_continue: ;
string text = _input.GetText(Interval.Of(_tokenStartCharIndex, _input.Index));
string msg = "token recognition error at: '" + GetErrorDisplay(text) + "'";
IAntlrErrorListener<int> listener = ErrorListenerDispatch;
listener.SyntaxError(this, 0, _tokenStartLine, _tokenStartColumn, msg, e);
listener.SyntaxError(ErrorOutput, this, 0, _tokenStartLine, _tokenStartColumn, msg, e);
}
public virtual string GetErrorDisplay(string s)

View File

@ -169,13 +169,15 @@ namespace Antlr4.Runtime
private int _syntaxErrors;
protected readonly TextWriter Output;
protected readonly TextWriter ErrorOutput;
public Parser(ITokenStream input) : this(input, Console.Out) { }
public Parser(ITokenStream input) : this(input, Console.Out, Console.Error) { }
public Parser(ITokenStream input, TextWriter output)
public Parser(ITokenStream input, TextWriter output, TextWriter errorOutput)
{
TokenStream = input;
Output = output;
ErrorOutput = errorOutput;
}
/// <summary>reset the parser's state</summary>
@ -688,7 +690,7 @@ namespace Antlr4.Runtime
charPositionInLine = offendingToken.Column;
}
IAntlrErrorListener<IToken> listener = ((IParserErrorListener)ErrorListenerDispatch);
listener.SyntaxError(this, offendingToken, line, charPositionInLine, msg, e);
listener.SyntaxError(ErrorOutput, this, offendingToken, line, charPositionInLine, msg, e);
}
/// <summary>

View File

@ -4,6 +4,7 @@
*/
using System;
using System.Collections.Generic;
using System.IO;
namespace Antlr4.Runtime
{
/// <summary>
@ -35,11 +36,11 @@ namespace Antlr4.Runtime
}
}
public virtual void SyntaxError(IRecognizer recognizer, Symbol offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e)
public virtual void SyntaxError(TextWriter output, IRecognizer recognizer, Symbol offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e)
{
foreach (IAntlrErrorListener<Symbol> listener in delegates)
{
listener.SyntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e);
listener.SyntaxError(output, recognizer, offendingSymbol, line, charPositionInLine, msg, e);
}
}
}

View File

@ -5,12 +5,13 @@
using Antlr4.Runtime;
using Antlr4.Runtime.Sharpen;
using Antlr4.Runtime.Tree.Xpath;
using System.IO;
namespace Antlr4.Runtime.Tree.Xpath
{
public class XPathLexerErrorListener : IAntlrErrorListener<int>
{
public virtual void SyntaxError(IRecognizer recognizer, int offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e)
public virtual void SyntaxError(TextWriter output, IRecognizer recognizer, int offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e)
{
}
}

View File

@ -358,10 +358,10 @@ case <f.ruleIndex> : return <f.name>_sempred(<if(!recog.modes)>(<f.ctxType>)<end
>>
parser_ctor(parser) ::= <<
public <csIdentifier.(parser.name)>(ITokenStream input) : this(input, Console.Out) { }
public <csIdentifier.(parser.name)>(ITokenStream input) : this(input, Console.Out, Console.Error) { }
public <csIdentifier.(parser.name)>(ITokenStream input, TextWriter output)
: base(input, output)
public <csIdentifier.(parser.name)>(ITokenStream input, TextWriter output, TextWriter errorOutput)
: base(input, output, errorOutput)
{
Interpreter = new ParserATNSimulator(this, _ATN, decisionToDFA, sharedContextCache);
}
@ -1005,10 +1005,10 @@ public partial class <csIdentifier.(lexer.name)> : <superClass; null="Lexer"> {
<namedActions.members>
public <csIdentifier.(lexer.name)>(ICharStream input)
: this(input, Console.Out) { }
: this(input, Console.Out, Console.Error) { }
public <csIdentifier.(lexer.name)>(ICharStream input, TextWriter output)
: base(input, output)
public <csIdentifier.(lexer.name)>(ICharStream input, TextWriter output, TextWriter errorOutput)
: base(input, output, errorOutput)
{
Interpreter = new LexerATNSimulator(this, _ATN, decisionToDFA, sharedContextCache);
}