How to comment string starting with "//" this? - java

I am learning compiler construction these days, and I am having trouble while making the code for comment in it.
What is actually happening is that when ever I am writing a string in the notepad file such as Hello //World. Then it is printing "/" this div operator which I don't want. What actually I want is that Hello should be printed in the output and World should get commented. I know I have included the code for div operator but it is also necessary to include. Just wanted to know how I can achieve this comment logic while checking the logic for checking the div operator should also be there.
Here is the code!
import java.io.File;
import java.util.Scanner;
import java.io.FileNotFoundException;
public class main {
public static void main(String[] args) throws FileNotFoundException{
File newFile = new File("C:/temp/sourcecode.txt");
Scanner scanFile = new Scanner(newFile);
//Scanner scan = new Scanner(System.in);
char ch;
String str;
while(scanFile.hasNextLine()){
str = scanFile.nextLine();
int l = str.length();
if(!str.startsWith("//") && !str.startsWith("/*") && !str.endsWith("*/")) {
for(int i =0; i<l ; i++) {
ch = str.charAt(i);
System.out.println(ch);
if(ch == '*'){
System.out.println("The Operator is MUL");
System.out.println("arop\n");
}
if(ch == '/')
{
System.out.println("The Operator is DIV");
System.out.println("arop\n");
}
}
}
int OP = 0;
switch(OP){
case 0:
if(str.contains("<") && str.contains(">")){
System.out.println("The Operator is NE");
System.out.println("relop\n");
break;
}
case 1:
if(str.contains("<") && str.contains("=")){
System.out.println("The Operator is LE");
System.out.println("relop\n");
break;
}
case 2:
if(str.contains(">") && str.contains("=")){
System.out.println("The Operator is GE");
System.out.println("relop\n");
break;
}
case 3:
if(str.contains("<")){
System.out.println("The Operator is LT");
System.out.println("relop\n");
break;
}
case 4:
if(str.contains(">")){
System.out.println("The Operator is GT");
System.out.println("relop\n");
break;
}
case 5:
if(str.contains("==")){
System.out.println("The Operator is EQ");
System.out.println("relop\n");
break;
}
case 6:
if(str.contains("+")){
System.out.println("The Operator is ADD");
System.out.println("arop\n");
break;
}
case 7:
if(str.contains("-")){
System.out.println("The Operator is SUB");
System.out.println("arop\n");
break;
}
// case 8:
// if(str.contains("*")){
// System.out.println("The Operator is MUL");
// System.out.println("arop\n");
// break;
// }
// case 9:
// if(str.contains("/")){
// System.out.println("The Operator is DIV");
// System.out.println("arop\n");
// break;
// }
case 10:
if(str.contains("=")){
System.out.println("The Operator is ASN");
System.out.println("otop\n");
break;
}
case 11:
if(str.contains("'")){
System.out.println("The Operator is PRN");
System.out.println("otop\n");
break;
}
case 12:
if(str.contains(";")){
System.out.println("The Operator is LTRN");
System.out.println("otop\n");
break;
}
case 13:
if(str.contains("{")){
System.out.println("The Operator is LBRC");
System.out.println("otop\n");
break;
}
case 14:
if(str.contains("}")){
System.out.println("The Operator is RBRC");
System.out.println("otop\n");
break;
}
}
}
}
}
Thank you in advance!

When programming a compiler the different input words in your code are called tokens, and the phase of recognising the role of each token is called the lexical analysis phase.
When trying to recognise tokens usually what is used is regex which is a way of implementing a finite automata.
You can read about it in much more detail here:
https://en.wikipedia.org/wiki/Lexical_analysis
You should replace the usage of contains, and use a lexer, it's the name of the tool that does lexical analysis. It uses regexes because it's not just about / and //, there can be many different situations where your compiler will need to decide which token to choose.
Here's an example of a finite automate for recognising different tokens, notice that for each prefix there can be many options for possible tokens:
In Java you can use jflex which will generate lexer code with your tokens definitions.

When you find a /, you need to check the next character.
if (ch == '/') {
char nextCh = (i + 1 < l ? str.charAt(i + 1) : '\0');
if (nextCh == '/') {
System.out.println("The Operator is EndOfLineComment");
System.out.println("arop\n");
i++;
} else if (nextCh == '*') {
System.out.println("The Operator is TraditionalComment");
System.out.println("arop\n");
i++;
} else {
System.out.println("The Operator is DIV");
System.out.println("arop\n");
}
}

Related

Java Calculator char thread

This is my void main in my code. When I compile the code it shows no errors, But when I type any random letters then it shows the following thread.
Output:
Please enter the equation :
2323.10ffxcv
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextDouble(Scanner.java:2413)
at Calculator.main(calculator.java:31)
[This is the output in CMD.][1]
Code:
Calculator calc = new Calculator();
Scanner numbers = new Scanner(System.in);
System.out.println("Please enter the equation : ");
double a = numbers.nextDouble();
char sign = numbers.next().charAt(0);
double b = numbers.nextDouble();
switch (sign) {
case '+':
calc.add(a, b);
break;
case '-':
calc.sub(a, b);
break;
case '*':
calc.multiply(a, b);
break;
case '/':
calc.divide(a, b);
break;
default:
System.out.println("Sorry I ( The program ) did not understand");
while (sign != '+' || sign != '-' || sign != '*' || sign != '/') {
switch (sign) {
case '+':
calc.add(a, b);
break;
case '-':
calc.sub(a, b);
break;
case '*':
calc.multiply(a, b);
break;
case '/':
calc.divide(a, b);
break;
default:
System.out.println("Sorry I ( The program ) did not understand");
break;
}
}
break;
}
Please help!
The Scanner class won't tokenize your input the way you seem to assume. That is, numbers.nextDouble() doesn't read up until the end of the first bit of data that looks like a Double. It reads the entire line, and attempts to parse it as a Double. You get an InputMismatchException because the input (2323.10ffxcv) doesn't match the expected data type (Double).
You need to find a way to either tokenize the string yourself, or simply enter each value on its own line. Even so, the last part of your input (ffxcv) is still going to break things, because it can't be parsed as a Double.

nested switch case error with wrong output?

I am experiencing some problems with the output of my program. I am certain the error is logical but i just cant fix it. error should be somewhere around here
String plusorminus ="+-";
char mark = plusorminus.charAt(0);
char modifier = 0;
if(plusorminus.length() >= 1)
{
modifier = plusorminus.charAt(1);
}
/*This is my utility scanner,
* I created char grade to get the user input.
*/
java.util.Scanner input=new java.util.Scanner(System.in);
String userInputString = input.nextLine();
char grade = userInputString.charAt(0);
I don't know how to fix it. At the moment if i insert A+ to the program it would give me the result for A-. Heres my full code.
public class SwitchCase {
public static void main(String[] args) {
System.out.println("Please enter your grade (ex.A+) to get the mark range");
/*This block of codes converts from string to
* char and it gets the plus or minus sign
*/
String plusorminus ="+-";
char mark = plusorminus.charAt(0);
char modifier = 0;
if(plusorminus.length() >= 1)
{
modifier = plusorminus.charAt(1);
}
/*This is my utility scanner,
* I created char grade to get the user input.
*/
java.util.Scanner input=new java.util.Scanner(System.in);
String userInputString = input.nextLine();
char grade = userInputString.charAt(0);
/*This set of code contains the nested switch statements
* that i will use to output the correct mark range
* to the user. It also contains a try statement to find runtime
* errors in the program.
*/
try{
switch(grade)
{
case 'A':
switch(modifier)
{
case '+': System.out.println("Your grade is 90-99.99%"); break;
case '-': System.out.println("Your grade is 80-84.99%"); break;
default: System.out.println("Your grade is 85-89.99%"); break;
}
break;
case 'B':
switch(modifier)
{
case'+': System.out.println("Your grade is 77.00 - 79.99%"); break;
case'-': System.out.println("Your grade is 70.00 - 72.99%"); break;
default: System.out.println("Your grade is 73.00 - 76.99%"); break;
}
break;
case 'C':
switch(modifier)
{
case'+': System.out.println("Your grade range is 67.00 - 69.99%"); break;
case'-': System.out.println("Your grade range is 60.00 - 62.99%"); break;
default: System.out.println("Your grade range is 63.00 - 66.99%"); break;
}
break;
case 'D':
switch(modifier)
{
case'+': System.out.println("Your grade range is 55.00 - 59.99%"); break;
case'-': System.out.println("-"); break;
default: System.out.println("Your grade range is 50.00 - 54.99%"); break;
}
break;
case 'F':
switch(modifier)
{
default: System.out.println("Your grade range is 0.00-49.99%"); break;
}
break;
}
}
catch (java.util.InputMismatchException e) { //if the above error is met, message will be sent to the user
System.out.println("Please enter a valid grade!");
}
input.close(); //ends the user input
}
}
After
char grade = userInputString.charAt(0);
add
char modifier = ' ';
if( userInputString.length() > 1 ){
modifier = userInputString.charAt(1);
}
and remove the code dealing with plusorminus.
You should also add some code to avoid hiccups after reading the input line.
userInputString = userInputString.trim(); // maybe user hits space?
if( ! userInputString.matches( "^[A-F][-+]?$" ) ){
// error message...
}
Not sure whether there is E, and F+ or F-?? We have different grades. Perhaps the regex should be
"^[A-E][-+]?|F$"
You might be inserting
A+
but you're only consuming the A.
String userInputString = input.nextLine();
char grade = userInputString.charAt(0);
The modifier is assigned, deterministically, here
String plusorminus ="+-";
char mark = plusorminus.charAt(0);
char modifier = 0;
if(plusorminus.length() >= 1)
{
modifier = plusorminus.charAt(1);
}
The length of plusorminus will always be 2 which means that modifier will always be plusorminus.charAt(1), ie. -. You want to assign the second character of your input string as the modifier.

On Switch How to use logic operator on case JAVA

i have a problem i dont know what to put on case section, when ever the user input their grades from 0-100 there are output corresponds to their grades failed,good,verygood,excellent.
import java.util.Scanner;
public class ProgTestI {
public static void main (String args[]){
Scanner pao = new Scanner(System.in);
System.out.print("Grades: ");
String grades = pao.next();
int grado = Integer.parseInt(grades);
switch (grado){
case =<74: /* iwant to put 0 to 74*/
System.out.println("Failed");
case : /* 75-80*/
System.out.println("bellow average");
case : /*81-85*/
System.out.println("average");
case : /*86-90*/
System.out.println("Good");
case : /*91-96*/
System.out.println("VeryGood");
default:
}
}
}
You cannot use switch for ranges, you need to replace this chunk of code with proper if/else blocks.
Switch works only on numeric values, but it works like
if(numericVal == 40)
So writing it for ranges is... waste of code, and not readable.
You need to rewrite it:
if( g <= 74){
...
}else if( g > 74 && g <= 80 ){
...
Your case code is incorrect, you can do as Beri mentioned.
If you want to implement switch statement in your application, then you can do as follows:
public static void main(String[] args) {
Scanner pao = new Scanner(System.in);
System.out.print("Grades: ");
String grades = pao.next();
int grado = Integer.parseInt(grades);
int checkedCase=0;
if(grado<=74){
checkedCase=1;
}
else if(grado>=75&&grado<=80){
checkedCase=2;
}
else if(grado>=81&&grado<=85){
checkedCase=3;
}
else if(grado>=86&&grado<=90){
checkedCase=4;
}
else if(grado>=91&&grado<=96){
checkedCase=5;
}
switch (checkedCase){
case 1: /* iwant to put 0 to 74*/
System.out.println("Failed");
break;
case 2: /* 75-80*/
System.out.println("bellow average");
break;
case 3: /*81-85*/
System.out.println("average");
break;
case 4: /*86-90*/
System.out.println("Good");
break;
case 5: /*91-96*/
System.out.println("VeryGood");
break;
default: System.out.println("Please enter a value in range 0-96");
break;
}
}

How to break out of loop when case is selected

I have a code that has 4 cases and I am trying to break the loop and if the 'f' case is chosen. and then choose from that case. When i try to do the if statement with the break over 30 errors but when I take it away the code is fine.
String one = "";
boolean yea = true;
Scanner sw = new Scanner(System.in);
while (yea == true)
{
System.out.print(MENU);
one = sw.next();
char choice = one.charAt(0);
switch(choice)
{
case 'f':
friendsList();
break;
case 'w':
wall();
break;
case 'p':
network();
break;
case 'q' :
yea = false;
break;
default:
System.out.println("Error: You have entered " + choice +
". Please try again");
}
}
if (case == 'f')
{
break;
}
}
You would use a Java label (see this code example named BreakWithLabelDemo.java) to tell your code where to break.
myloop:
while ( true ){
switch( choice ){
case 'f':
friendsList();
break myloop;
}
}
For your implementation, it would make sense to break on a specific case before even entering the switch statement. For example:
char choice = one.charAt(0);
if (choice == 'f') break;
switch(choice)
This seems to be a pretty simple way to exit the while loop without conflicting with the break statements of the switch statement.
Or if you still need to call the friendsList method when choice is 'f' you can move that if statement to after the switch statement.
Note: With this you should also remove the if statement at the bottom of your code example.
if (case == 'f')
What is case in this statement? You should replace that with choice.
if (choice == 'f')
you need to put if inside while loop.
String one = "";
boolean yea = true;
Scanner sw = new Scanner(System.in);
while (yea == true)
{
System.out.print(MENU);
one = sw.next();
char choice = one.charAt(0);
switch(choice)
{
case 'f':
friendsList();
break;
case 'w':
wall();
break;
case 'p':
network();
break;
case 'q' :
yea = false;
break;
default:
System.out.println("Error: You have entered " + choice +
". Please try again");
}
if (choice == 'f')
{
break;
}
}
The if statement should be moved inside of the while loop to be effective, and case inside the if statement should be changed to choice.
so
While(yea==true)
{
System.out.print(MENU);
one = sw.next();
char choice = one.charAt(0);
if(choice == 'F')
{
break;
}
switch(choice)
{
//cases
}
}

sorting by first character

The question at hand is each policy No. is a string of 9 characters of which indicates the type of insurance policy
B for building policy
C for Contents Policy
L for Life policy
V for car policy
Each of the remaining 8 characters of the policy number is a decimal digit.
I have tried using charAt but somebody told me there was a slightly better way
public String getpolicyNo(String initpolicyNo) {
/**
* Access method to find the first character of the policy to then
* determine what type of policy it is.
*/
String b = "B";
String C = "C";
String L = "L";
String V = "V";
char c1 = b.charAt(0);
char c2 = C.charAt(0);
char c3 = L.charAt(0);
char c4 = V.charAt(0);
if (c1 == 0) {
System.out.println("Its building" + c1);
return initpolicyNo;
} else {
if (c2 == 0) {
System.out.println("Its Content");
return initpolicyNo;
} else {
if (c3 == 0) {
System.out.println("Its life");
return initpolicyNo;
} else {
if (c4 == 0) {
System.out.println("Its car");
return initpolicyNo;
}
}
}
}
throw new IllegalArgumentException();
}
I'm not looking for you to provide an answer for me, I'm just looking for any possible alternatives and possible suggestions.
Many thanks
Dan
I'm not really sure what you are trying to achieve, but I would write this way:
public String getpolicyNo(String initpolicyNo) {
switch(initPolicyNo.charAt(0))
{
case 'B':
System.out.println("Its building B");
return initpolicyNo;
case 'C':
System.out.println("Its building C");
return initpolicyNo;
case 'L':
System.out.println("Its building L");
return initpolicyNo;
case 'V':
System.out.println("Its building V");
return initpolicyNo;
}
throw new IllegalArgumentException();
}
I recommend you using an Enum. Each value for an Enum has an ordinal value, which you can sort by.
If you want to read an introduction to Enums, the following site will help: Enum Types - The Java Tutorials
enum Policy {
BUILDING_POLICY, CONTENTS_POLICY, LIFE_POLICY, CAR_POLICY
}
For each enum value, you can assign a custom value, with which you can sort.
public void whatItIs(String s){
if(s.length() < 1){
//-- nothing to see here ---
return;
}
//-- case insensitive --
char c = Character.toUpperCase(s.charAt(0));
switch(c){
case 'B':
//-- its a building !--
break;
case 'C':
//-- its a c........ !--
break;
case 'L':
//-- its a l........ !--
break;
case 'V':
//-- its a v........ !--
break;
default:
//-- its something else :(--
}
}
public String getpolicyNo(String initpolicyNo) {
switch (initpolicyNo.charAt(0)) {
case 'B':
System.out.println("Its building" );
break;
case 'C':
System.out.println("Its Content");
break;
case 'L':
System.out.println("Its life");
break;
case 'V':
System.out.println("Its car");
break;
default:
throw new IllegalArgumentException();
break;
}
return initpolicyNo;
}
You could add enums to your code, or you could use a switch statement instead of the if/else block you currently have:
char type = initpolicyNo.charAt(0);
switch (type) {
case 'B':
// do stuff
break;
case 'C':
// do stuff
break;
}
Note: I think you may have a problem in your code in that it seems to me you should be switching on the initpolicyNo, not the actual types?
I have tried using charAt but somebody told me there was a slightly
better way
there is no better way to get the first letter of a string than using charAt.
And rather than having lots of if's/switches and what not, get a bit more OOPs up side your head.
Map<Character, String> myMap = new HashMap<Character, String>() {{
put('B', "Its building");
put('C', "Its content");
put('L', "its life");
put('V', "its vehicle");
}} ;
public void iShouldBeDoingMyOwnWork(String initpolicyNo) {
System.out.println(myMap.get(initpolicyNo.charAt(0)));
}

Categories