I have a lexer that accepts Reader object. Initially it is intended to parse files, but
I want to run lexer with stdin to make a repl
so, here is my code
private static void launchRepl() {
final var reader = new BufferedReader(new InputStreamReader(System.in));
while (true) {
System.out.print("> ");
var lexer = new Lexer(reader);
while (true) {
var token = lexer.readToken();
var ttype = token.tokenType();
if (ttype == TokenType.Eof || ttype == TokenType.StatementEnd) {
break;
}
System.out.println(token);
}
}
}
In the language i tokenize, new line is of TokenType.StatementEnd. But when I write new input to the console and hit enter, my lexer does not see this new line character and blocks, until i press enter one more time. So it works like:
> 1 + 2
Number 1
Operator +
Number 2
(waiting for another enter) *hits enter*
>
I want to fix so it sees \n at the end of the prompt
Related
I'm trying to read from the user's input from command line. For the input for filename, the program is supposed to exit whenever it detects that the user has submitted a blank value.
However, the program is always going to the "Inside Reading file" code, regardless of whether the user input contains anything or not. It never gets to execute the "Program will exit now" code. I've tried different ways of coding it, and all of them came back with the same results. Is there anything wrong with it?
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String collection;
String filename;
System.out.println("Enter the collection name: ");
collection = br.readLine();
String urlString = "http://localhost:8983/solr/" + collection;
solr = new HttpSolrClient(urlString);
doc1 = new SolrInputDocument ();
while (true){
System.out.println("Enter the file name: ");
while ((filename = br.readLine()) !=null) {
System.out.println("Inside reading file ");
parseUsingStringTokenizer(filename);
System.out.println("Enter the file name: ");
}
System.out.println("Program will exit now...");
System.exit(0);
}
}
add one extra condition filename.trim().length()>0 with (filename = br.readLine()) !=null. As != null will not check for whitespaces. And why you have put while(true). It is useless as per your current code.
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String collection;
String filename;
System.out.println("Enter the collection name: ");
collection = br.readLine();
String urlString = "http://localhost:8983/solr/" + collection;
solr = new HttpSolrClient(urlString);
doc1 = new SolrInputDocument ();
System.out.println("Enter the file name: ");
while ((filename = br.readLine()) !=null && filename.trim().length()>0){
System.out.println("Inside reading file ");
parseUsingStringTokenizer(filename);
System.out.println("Enter the file name: ");
}
System.out.println("Program will exit now...");
}
BufferedReader returns null when the end of stream is reached. It returns "" (the empty string of length 0) when the user enters a blank line.
Thus, you should change your loop condition to this:
while (!(filename = br.readLine()).equals(""))
the code below is from a reference i saw online, so there might be some similarities i'm trying to implement the code to remove an entire line based on the 1st field in this instance it is (aaaa or bbbb) the file which has a delimiter "|", but it is not working. Hope someone can advise me on this. Do i need to split the line first? or my method is wrong?
data in player.dat (e.g)
bbbb|aaaaa|cccc
aaaa|bbbbbb|cccc
Code is below
public class testcode {
public static void main(String[] args)throws IOException
{
File inputFile = new File("players.dat");
File tempFile = new File ("temp.dat");
BufferedReader read = new BufferedReader(new FileReader(inputFile));
BufferedWriter write = new BufferedWriter(new FileWriter(tempFile));
Scanner UserInput = new Scanner(System.in);
System.out.println("Please Enter Username:");
String UserIn = UserInput.nextLine();
String lineToRemove = UserIn;
String currentLine;
while((currentLine = read.readLine()) != null) {
// trim newline when comparing with lineToRemove
String trimmedLine = currentLine.trim();
if(trimmedLine.equals(lineToRemove)) continue;
write.write(currentLine + System.getProperty("line.separator"));
}
write.close();
read.close();
boolean success = tempFile.renameTo(inputFile);
}
}
Your code compares the entire line it reads from the file to the user name the user enters, but you say in your question that you actually only want to compare to the first part up to the first pipe (|). Your code doesn't do that.
What you need to do is read the line from the file, get the part of the string up to the first pipe symbol (split the string) and skip the line based on comparing the first part of the split string to the lineToRemove variable.
To make it easier, you could also add the pipe symbol to the user input and then do this:
string lineToRemove = UserIn + "|";
...
if (trimmedLine.startsWith(lineToRemove)) continue;
This spares you from splitting the string.
I'm currently not sure whether UserInput.nextLine(); returns the newline character or not. To be safe here, you could change the above to:
string lineToRemove = UserIn.trim() + "|";
For the following code:
String line = new String("Hello World!");
Scanner scan = new Scanner(line);
I'm trying to change the source for scan from line to another String. Is there any way to specify a new source for a Scanner object without having to close it and create a new object with a new source?
EDIT:
In the program that uses this code, I use a buffered stream to read text line-by-line into the program, use a Scanner object to pick out the individual words, convert each word using the shiftWord method, and use another buffer to write it out to a separate file.
try(InputStream in = new FileInputStream(this.fileRead)) {
Reader reader = new InputStreamReader(in, "UTF-8");
BufferedReader buffIn = new BufferedReader(reader);
try(OutputStream out = new FileOutputStream(this.fileWrite)) {
Writer writer = new OutputStreamWriter(out, "UTF-8");
BufferedWriter buffOut = new BufferedWriter(writer);
String line = new String();
Scanner scan = new Scanner(line);
line = buffIn.readLine();
String token = new String();
String sentence;
String message = new String();
while(line != null) {
line += "/stop/";
sentence = "";
do {
token = scan.next();
sentence += (shiftWord(token) + " ");
} while(!token.endsWith("/stop/"));
message += sentence + "\n";
line = buffIn.readLine();
}
buffOut.write(message);
scan.close();
buffOut.close();
} catch (IOException x) {
System.out.println("IOException: Write Error!");
}
buffIn.close();
} catch (IOException x) {
System.out.println("IOException: Read Error!");
}
The code compiles fine, however running it causes NoSuchElementExceptionat this line:
token = scan.next();
I did some debugging, and what I found is that the problem lies with:
line += "stop";
because this line appears inside the while loop after I declare the Scanner.
To solve this, I would have to declare the Scanner after this line, which is inside the while loop.
Yet, I dislike the idea of declaring the Scanner inside the while loop because this will create a new Scanner object with every iteration of the while loop. If possible I'd like to:
Declare the Scanner object outside the loop
Update the source for the Scanner object from within the loop.
Basically, reuse the Scanner object.
If you can help me, it would be greatly appreciated.
EDIT: I would also like to pass whitspace, in the same format it takes in the original text file to the text file being written.
You can't change Scanner's underlying input stream -- it's designed to read from a single input until it is empty. You could probably wrap the scanner around a SequentialInputStream wrapped around a LinkedList of ByteArrayInputStreams which could then be extended at runtime, but I'm having difficulties imagining a situation where this would be a good idea.
In your case: why not wrap the Scanner directly around buffIn? Configure the Scanner to not ignore newlines as you are using them (useDelimiter("[\\s&[^\\n\\r]]*")). This way, you only need to create one Scanner.
EDIT: This example uses word boundaries as delimiters:
public class ScannerExample {
public static void main(String[] args) {
Scanner s = new Scanner("this is a \n\tTest");
s.useDelimiter("\\b");
while (s.hasNext()) {
String token = s.next();
System.out.println("\"" + StringEscapeUtils.escapeJava(token)
+ "\"\tapply shiftToken = " + !token.matches("\\A\\s+\\z"));
}
}
}
Output:
"this" apply shiftToken = true
" " apply shiftToken = false
"is" apply shiftToken = true
" " apply shiftToken = false
"a" apply shiftToken = true
" \n\t" apply shiftToken = false
"Test" apply shiftToken = true
So I have an assignment that requires me to "Search a file line by line for a given string. The output must contain the line number, and the line itself, for example if the word files was picked the output look something like
5: He had the files
9: the fILEs were his
Code:
void Search(String input) throws IOException {
int x = 1;
FileReader Search = new FileReader(f);
Scanner in = new Scanner(f);
LineNumberReader L = new LineNumberReader(Search, x);
StreamTokenizer token = new StreamTokenizer(Search);
while (in.hasNextLine())
{
try
{
if (!in.findInLine(input).isEmpty())
{
display(Integer.toString(L.getLineNumber()) + ": " + L.readLine(), "\n");
in.nextLine();
}
} catch (NullPointerException e)
{
System.out.println("Something Happened");
in.nextLine();
}
}
}
So far there are 3 issues I need to figure out with my code.
As soon as instance occurs where the searched is not in a line, it immediately displays the next line, even though the searched word is not in the line, and then terminates from there without having displayed the rest of the lines that had the word in it.
It supposed to display lines with the word, regardless of casing, but does not.
Preferably, it's supposed to display all of them at once, but instead is displaying line by line, until it errors out and terminates.
You're main problem is here...
FileReader Search = new FileReader(f);
Scanner in = new Scanner(f);
LineNumberReader L = new LineNumberReader(Search, x);
StreamTokenizer token = new StreamTokenizer(Search);
while (in.hasNextLine())
{
You've basically opened two file readers against the same file, but you seem to be expecting them to know about each other. You advance the Scanner, but that has no effect on the LineNumberReader. This then messes up the reporting and line reading process.
Reading from Scanner should look more like...
while (in.hasNextLine()) {
String text = in.nextLine();
Having said that, I'd actually drop the Scanner in favor of the LineNumberReader as it will provide you with more useful information which you would otherwise have to do yourself.
For example...
FileReader Search = new FileReader(new File("TestFile"));
LineNumberReader L = new LineNumberReader(Search, x);
String text = null;
while ((text = L.readLine()) != null) {
// Convert the two values to lower case for comparison...
if (text.toLowerCase().contains(input.toLowerCase())) {
System.out.println(L.getLineNumber() + ": " + text);
}
}
My java code takes almost 10-15minutes to run (Input file is 7200+ lines long list of query). How do I make it run in short time to get same results?
How do I make my code to search only for aA to zZ and 0 to 9??
If I don't do #2, some characters in my output are shown as "?". How do I solve this issue?
// no parameters are used in the main method
public static void main(String[] args) {
// assumes a text file named test.txt in a folder under the C:\file\test.txt
Scanner s = null;
BufferedWriter out = null;
try {
// create a scanner to read from the text file test.txt
FileInputStream fstream = new FileInputStream("C:\\user\\query.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
// Write to the file
out = new BufferedWriter(new FileWriter("C:\\user\\outputquery.txt"));
// keep getting the next String from the text, separated by white space
// and print each token in a line in the output file
//while (s.hasNext()) {
// String token = s.next();
// System.out.println(token);
// out.write(token + "\r\n");
//}
String strLine="";
String str="";
while ((strLine = br.readLine()) != null) {
str+=strLine;
}
String st=str.replaceAll(" ", "");
char[]third =st.toCharArray();
System.out.println("Character Total");
for(int counter =0;counter<third.length;counter++){
//String ch= "a";
char ch= third[counter];
int count=0;
for ( int i=0; i<third.length; i++){
// if (ch=="a")
if (ch==third[i])
count++;
}
boolean flag=false;
for(int j=counter-1;j>=0;j--){
//if(ch=="b")
if(ch==third[j])
flag=true;
}
if(!flag){
System.out.println(ch+" "+count);
out.write(ch+" "+count);
}
}
// close the output file
out.close();
} catch (IOException e) {
// print any error messages
System.out.println(e.getMessage());
}
// optional to close the scanner here, the close can occur at the end of the code
finally {
if (s != null) {
// close the input file
s.close();
}
}
}
For something like this I would NOT recommend java though it entirely possible it is much easier with GAWK or something similar. GAWK also has java like syntax so its easy to pick up. You should check it out.
SO isn't really the place to ask such a broad how-do-I-do-this-question but I will refer you to the following page on regular expression and text match in Java. Also, check out the Javadocs for regexes.
If you follow that link you should get what you want, else you could post a more specific question back on SO.