Scanning , Parsing - c#

I'm writing simple compiler without using grammar Generators. Here
. I wrote the scanning code that read file.txt ,and classify it to Identifier or Revers words , Number , Variable ..etc.
I got the result that I want but Is it possible to complete with this code I mean applying syntax Analysis ? and parsing ? . Because I I tried make it with java and I coded it with wrong way . I want see if I do it right ,specially i'm not good in C# codding .
Arrays :
string[] Rw = new string[8];
Rw[0] = "for";
Rw[1] = "while";
Rw[2] = "end";
Rw[3] = "contiune";
Rw[4] = "if";
Rw[5] = "break";
Rw[6] = "do";
Rw[7] = "return";
string[] id = new string[6];
id[0] = "int";
id[1] = "float";
id[2] = "string";
id[3] = "double";
id[4] = "bool";
id[5] = "char";
string[] op = new string[6];
op[0] = "+";
op[1] = "-";
op[2] = "/";
op[3] = "*";
op[4] = "%";
string[] Num = new string[10];
Num[0] = "0";
Num[1] = "1";
Num[2] = "2";
Num[3] = "3";
Num[4] = "4";
Num[5] = "5";
Num[6] = "6";
Num[7] = "7";
Num[8] = "8";
Num[9] = "9";
string[] var = new string[17];
var[0] = "a";
var[1] = "b";
var[2] = "A";
var[3] = "B";
var[4] = "C";
var[5] = "d";
var[6] = "D";
var[7] = "X";
var[8] = "x";
var[9] = "Y";
var[10] = "y";
var[11] = "z";
var[12] = "Z";
var[13] = "v";
var[14] = "V";
var[15] = "f";
var[16] = "F";
Reading and Split :
char[] delimiterChars = { ' ', ',', '.', ':', '\t' };
using (System.IO.StreamReader file = new System.IO.StreamReader(#"C:\Users\caza\Desktop\1.txt"))
{
while ((line = file.ReadLine()) != null)
{
string[] token = line.Split(delimiterChars);
foreach (string s in token)
{
// Console.WriteLine(s);
foreach (string z in Rw)
{
if (s == z)
{
Console.WriteLine(s + " is a Reserved Word ");
}
}
foreach (string y in id)
{
if (s == y)
{
Console.WriteLine(s + " is a identifier ");
}
}
foreach (string o in op)
{
if (s == o)
{
Console.WriteLine(s + " is a Operation ");
}
}
foreach (string n in Num)
{
if (s == n)
{
Console.WriteLine(s + " is a Number ");
}
}
foreach (string v in var)
{
if (s == v)
{
Console.WriteLine(s + " is a Variable");
}
}
}
}
}
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}

Related

How to mask string after first character

Let's say I have a string that consists of a person's name:
var name = "Jason, Bruno Mars";
How do I mask the string with X for the name behind the comma and returns:
var name = "Jason, BXXXX MXXX";
I have tried using the following methods but only front characters are masked:
string first, second, output;
bool hasSpace, hasComma;
int int_LENGTH;
var name = "Jason, Bruno Mars";
hasComma = name.Contains(",");
if (hasComma == true)
{
int_LENGTH = name.IndexOf(",");
if (int_LENGTH > 0)
{
first = name.Substring(0, int_LENGTH);
}
second = string.Join(",", name.Split(" ").Skip(1));
hasSpace = second.Contains(" ");
if (hasSpace == true)
{
second = string.Concat(new string('X', 12), second.Substring(second.Length - 4));
output = first + "," + second;
}
}
Anyone has a better idea of how can I achieve the same result in a more efficient way?
Another option, using Regex.Matches to select the name parts except the first letter. The regex collects all string parts separated by a space, skipping what's before the comma.
The collections of Matches is then passed to Linq's Aggregate() method to perform the substitution.
A StringBuilder is used to store the strings generated by its own Replace() method:
string theName = "Jason Et Alt., Bruno Mars And More Names";
var matches = Regex.Matches(theName, #"(?!.*?,)\s+?.(\w+)");
string outName = matches.OfType<Match>().Aggregate(new StringBuilder(theName), (sb, m) =>
sb.Replace(m.Groups[1].Value, new string('X', m.Groups[1].Length))).ToString();
outname = Jason Et Alt., BXXXX MXXX AXX MXXX NXXXX
static string MaskName(string name)
{
string maskedString = string.Empty;
string[] names = name.Split(',');
if (names.Length > 0)
{
maskedString = names[0] + ",";
}
if (names.Length > 1)
{
string[] arrName = names[1].Split(' ');
foreach (string s in arrName)
{
if (s.Length > 0)
maskedString += " " + s[0].ToString().PadRight(s.Length, 'X');
}
}
return maskedString;
}
Using This code..
static string MaskName(string name)
{
string maskedString = string.Empty;
string[] names = name.Split(',');
if (names.Length > 0)
{
maskedString = names[0] + ",";
}
if (names.Length > 1)
{
string[] arrName = names[1].Split(' ');
foreach (string s in arrName)
{
if (s.Length > 0)
maskedString += " " + s[0].ToString().PadRight(s.Length, 'X');
}
}
return maskedString;
}
Output :-
Try This
private string ReturnMaskedName(string name)
{
string temporary = "";
var newname = (name.Split(new string[] { "," }, StringSplitOptions.None)[1].Trim().Split(new String[] { " " }, StringSplitOptions.None));
foreach (string allnames in newname)
{
temporary = temporary + " " + allnames[0].ToString() + new string('X', allnames.Length - 1);
}
return name.Split(new string[] { " " }, StringSplitOptions.None)[0] + " " + temporary;
}
Efficient way of masking without Split, Regex, and using System.Linq:
For C# version < 7.2:
static string MaskName(string name)
{
int indexOfComma = name.IndexOf(',');
if (indexOfComma != -1)
{
char[] temp = name.ToCharArray();
bool isFirstChar = true;
for (int i = indexOfComma + 1; i < temp.Length; i++)
{
if (temp[i] == ' ')
isFirstChar = true;
else if (isFirstChar)
isFirstChar = false;
else
temp[i] = 'X';
}
return new string(temp);
}
else
{
return name;
}
}
For C# version >= 7.2:
static string MaskName(ReadOnlySpan<char> name)
{
int indexOfComma = name.IndexOf(',');
if (indexOfComma != -1)
{
Span<char> temp = stackalloc char[name.Length];
name.CopyTo(temp);
bool isFirstChar = true;
for (int i = indexOfComma + 1; i < temp.Length; i++)
{
if (temp[i] == ' ')
isFirstChar = true;
else if (isFirstChar)
isFirstChar = false;
else
temp[i] = 'X';
}
return new string(temp);
}
else
{
return name.ToString();
}
}
private string MaskName(string name)
{
var parts = name.Split(',');
var subparts = parts[1].Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
for (var i = 0; i < subparts.Length; i++)
{
var subpart = subparts[i];
subparts[i] = subpart[0] + new string('X', subpart.Length - 1);
}
return parts[0] + ", " + string.Join(" ", subparts);
}

How should I coloring the letters like the game "Lingo"

I'm creating the same word-only game of Lingo (See video on YouTube). My issue is that the yellow blocks (in word but out of place) are not correctly displayed. All letters are displayed yellow, but out of place. What should happend that the number of yellow letters are representative from those who are out of order. What I have to get the mistery word:
Label[,] labels = new Label[6, 5]{ {l01, l02, l03, l04, l05} ,
{l06, l07, l08, l09, l10} ,
{l11, l12, l13, l14, l15} ,
{l16, l17, l18, l19, l20} ,
{l21, l22, l23, l24, l25} ,
{l26, l27, l28, l29, l30} ,
};
TableLayoutPanel[,] blocks = new TableLayoutPanel[6, 5]{ {v1, v2, v3, v4, v5} ,
{v6, v7, v8, v9, v10} ,
{v11, v12, v13, v14, v15} ,
{v16, v17, v18, v19, v20} ,
{v21, v22, v23, v24, v25} ,
{v26, v27, v28, v29, v30} ,
};
Label[,] l = labels;
TableLayoutPanel[,] v = blocks;
public static string first_word File.ReadLines(#"link to text file").Skip(word_number - 1)
public string[] mistery_word = first_word.Select(c => c.ToString()).ToArray();
public string[] compair_letters = { " ", " ", " ", " ", " "};
public string[] correct_letters = { " ", " ", " ", " ", " "};
When pressing the letters at keyboard, the labels in the square are changing. Hitting enter will check:
int a = 0;
int b = 0;
int c = 0;
for (a = 0; a < 5; a++)
{
if (l[current_line, a].Text == mistery_word[a]) // So the same = correct
{
compair_letters[a] = "0";
correct_letters[a] = l[current_line, a].Text;
}
}
for (a = 0; a < 5; a++)
{
if (mistery_word.Contains(l[current_line, a].Text))
{
compair_letters[a] = "1";
}
}
for (c = 0; c < 5; c++)
{
switch (compair_letters[c])
{
case "0":
Correct here
case "1":
Half here;
case "2":
Wrong here
default:
Wrong
}
}
Also I'm looping 3x (3rth is coloring). Is there a smarter way?
The second loop something like (untested!):
for (a = 0; a < 5; a++)
{
String current_letter = l[current_line, a].Text;
String correctLetters = ""
for (b=0; b<5; b++) { if (b!=a) { correctLetters += correct_letters[b]; }}
if (mistery_word.Contains(current_letter) && !correctLetters.Contains(current_letter) )
{
compair_letters[a] = "1";
}
}
After thinking a bit more about this, I created next thing:
public static string[] check_word_for_lingo(string guess, string secret_word)
{
String[] checks = new string[5];
char[] remainingLettersToCheck = secret_word.ToCharArray();
char[] secretWordLetters = secret_word.ToCharArray();
for (int a=0; a<5; a++)
{
if (guess[a]==secret_word[a])
{
checks[a] = "0"; remainingLettersToCheck[a] = ' ';
} else {
checks[a] = " ";
}
}
secret_word = new string(remainingLettersToCheck);
for (int a = 0; a < 5; a++)
{
if (remainingLettersToCheck[a] != ' ')
{
if (guess[a] != ' ' && secret_word.Contains(guess[a]))
{
checks[a] = "1"; remainingLettersToCheck[a] = ' ';
}
else
{
checks[a] = "2";
}
}
}
return checks;
}
it's used like this:
String[] checks = new string[5];
string guess = "SOEEE";
string secret_word = "SMORE";
checks = check_word_for_lingo(guess, secret_word);
Console.WriteLine(guess);
Console.WriteLine(secret_word);
int i = 0;
foreach (var item in checks)
{
Console.Write(item);
i++;
}
Which will output:
SOEEE
SMORE
01220
Testing with the word 'SOEOE' will still return a wrong answer (01210)

Error in generate code and Update list

i Try to make generate 16 bit code and when i add the record all number is same how can i fix it ?
in loop befor code[i] = Newcode; code is corect when code added in list changed last code to new so all code is same as last generate !!!!
public ActionResult Gen5Rm(GenerateCodeModel model){
Code Newcode = new Code();
int X = Convert.ToInt32(model.Quntity);
Code[] code = new Code[X];
for (int i = 0; i < X; i++)
{
string strDate = "";
string strmonth = "";
string strday = "";
string myday = "";
strmonth = DateTime.Now.ToString("MM");
myday = DateTime.Now.DayOfWeek.ToString();
if (myday == "Sunday")
{
strday = "SU";
}
if (myday == "Monday")
{
strday = "MO";
}
if (myday == "Tuesday")
{
strday = "TU";
}
if (myday == "Wednesday")
{
strday = "WE";
}
if (myday == "Thursday")
{
strday = "TU";
}
if (myday == "Friday")
{
strday = "FR";
}
if (myday == "Saturday")
{
strday = "ST";
}
strDate = generateBarcode();
Newcode.codebase = model.Agent + strmonth +
model.Type_Code + strDate + strday + "5" + model.Dealercode;
Newcode.price = 5;
Newcode.serial = "S" + DateTime.Now.ToString("mmssfff");
code[i] = Newcode;
}
return PartialView("_return5rm", code);
}
the export is like this
Newcode should be inside the for loop, otherwise all items in the array will point the same object (same memory address)
for (int i = 0; i < X; i++)
{
Code Newcode = new Code();
...
}

How to get output to be a continuous string rather than it being stacked on top of each letter - c#

public class LetterArray
{
internal static string[] Alphabet()
{
var letterValues = new string[26];
letterValues[0] = "A";
letterValues[1] = "B";
letterValues[2] = "C";
letterValues[3] = "D";
letterValues[4] = "E";
letterValues[5] = "F";
letterValues[6] = "G";
letterValues[7] = "H";
letterValues[8] = "I";
letterValues[9] = "J";
letterValues[10] = "K";
letterValues[11] = "L";
letterValues[12] = "M";
letterValues[13] = "N";
letterValues[14] = "O";
letterValues[15] = "P";
letterValues[16] = "Q";
letterValues[17] = "R";
letterValues[18] = "S";
letterValues[19] = "T";
letterValues[20] = "U";
letterValues[21] = "V";
letterValues[22] = "W";
letterValues[23] = "X";
letterValues[24] = "Y";
letterValues[25] = "Z";
return letterValues;
}
}
public class decrypt
{
public static void Main() //Main method
{
int res = 34;
string[] letterValues = LetterArray.Alphabet();
//Create for loop that runs through every possible shift value
for (int shift = 0; shift <= 25; shift++)
{
Console.WriteLine("\nShift Value = " + shift + ": ");
// For each character in the text file
foreach (var ch in ReadText.cipherTxt()) {
if (ch == ' ')
{ }
else
{
for (int i = 0; i <= 25; i++)
{
if ((ch.ToString().ToUpper()) == letterValues[i])
{
res = i;
}
}
if (shift > res)
{
Console.WriteLine(letterValues[26 - (shift - res)][0]);
}
else
{
Console.WriteLine(letterValues[res - shift][0]);
}
}
}
}
}
}
Not sure how to output the following so be a continuous string instead of each letter being stacked on top of each other. I have tried to change the Console.WriteLine values but it seems to mess the program up and throw an error instead.
Use Console.Write if you don't want each value in a new line.
Console.Write(letterValues[res - shift]);
You can also use a StringBuilder and Append characters to it. Then print it once after the loop.

Parallel.For error

Im trying to pare a DateTime in a Parallel.For:
part of the code:
public void LoadLogFile(String fileName) {
//Thread.CurrentThread.Priority = ThreadPriority.Lowest;
String currentFile = "";
if (fileName.Contains("Compass")) {
currentFile = "Compass";
CompassLogLoadCompleted = false;
compassLogCollection.Clear();
compassLogCollection.AsParallel();
} else if (fileName.Contains("")) {
currentFile = "CoreService";
CoreServiceLogLoadCompleted = false;
coreServiceLogCollection.Clear();
;
compassLogCollection.AsParallel();
} else {
Console.Out.WriteLine("Wrong File");
}
if (fileName.Contains("CoreService") ||
fileName.Contains("Compass")) {
int numberOfSingleLineLog = 0;
int numberOfmultipleLineLog = 0;
String[] lines = new string[] {};
String temp = "";
string[] parts;
DateTime dateTime = new DateTime();
LoggingLvl loggingLvl = new LoggingLvl();
LoggingLvl.ELoggingLvl eLoggingLvl = new LoggingLvl.ELoggingLvl();
int id = 0;
char[] delimiters = new[] {' '};
string threadId = "";
string loggingMessage;
string loggingMessage2 = "";
//string dateAndTimestamp = "";
int ff = 0;
// Read the File and add it to lines string
try {
swCompass.Start();
lines = File.ReadAllLines(fileName);
swCompass.Stop();
} catch (Exception e) {
CompassLogLoadCompleted = true;
CoreServiceLogLoadCompleted = true;
Console.WriteLine("The file could not be read:");
Console.WriteLine(e.Message);
}
swCompass.Reset();
swCompass.Start();
// Adding the objects to the collections
//compassLogCollection.EnableNotify = false;
Parallel.For(0, lines.Count(), j => {
//for (int i = 0; i < lines.Count(); i++) {
string dateAndTimestamp = "";
if (!CompassLogLoadCompleted || !CoreServiceLogLoadCompleted) {
try {
if (SingleLined(ref lines, j)) {
parts = lines[j].Split(delimiters,
StringSplitOptions.
RemoveEmptyEntries);
numberOfSingleLineLog++;
foreach (string t in parts) {
switch (ff) {
case 0:
dateAndTimestamp = t;
break;
case 1:
dateAndTimestamp += " " + t.Replace(",", ".");
dateTime = DateTime.Parse(dateAndTimestamp);
//dateTime = new DateTime();
dateAndTimestamp = "";
break;
case 2:
eLoggingLvl = loggingLvl.ParseLoggingLvl(t);
break;
case 3:
threadId = t;
break;
default:
temp += t;
break;
}
ff++;
}
loggingMessage = temp;
temp = "";
ff = 0;
id++;
loggingLvl = new LoggingLvl(eLoggingLvl);
if (fileName.Contains("Compass")) {
//CompassLogLoadPercent = ((double) numberOfSingleLineLog/lines.Count())*100;
CompassLogData cLD =
new CompassLogData(
(numberOfSingleLineLog +
numberOfmultipleLineLog),
dateTime,
loggingLvl, threadId,
loggingMessage);
//await addRoCompassLogCollectionAsync(cLD);
compassLogCollection.Add(cLD);
} else if (fileName.Contains("CoreService")) {
CoreServiceLogData cSLD =
new CoreServiceLogData(
(numberOfSingleLineLog +
numberOfmultipleLineLog),
dateTime,
loggingLvl,
threadId,
loggingMessage);
//await addRoCoreServiceCollectionAsync(cSLD);
coreServiceLogCollection.Add(cSLD);
} else {
Console.Out.WriteLine("File Not recognizable ");
}
//Console.Out.WriteLine(loggingMessage);
//loggingMessage = "";
} else {
loggingMessage2 += lines[j];
loggingMessage2 += "\n";
//parts[i] += lines[i];
//parts[i] += "\n";
if (NextLineIsANumber(ref lines, j)) {
numberOfmultipleLineLog++;
//Console.Out.WriteLine(loggingMessage2);
parts = loggingMessage2.Split(delimiters,
StringSplitOptions.
RemoveEmptyEntries);
foreach (string t in parts) {
switch (ff) {
case 0:
dateAndTimestamp = t;
break;
case 1:
dateAndTimestamp += " " +
t.Replace(",", ".");
//dateTime = DateTime.Parse(dateAndTimestamp);
dateTime = new DateTime();
dateAndTimestamp = "";
break;
case 2:
eLoggingLvl =
loggingLvl.ParseLoggingLvl(t);
break;
case 3:
threadId = t;
break;
default:
temp += t;
break;
}
ff++;
}
loggingMessage = temp;
temp = "";
ff = 0;
id++;
loggingLvl = new LoggingLvl(eLoggingLvl);
if (fileName.Contains("Compass")) {
CompassLogData cLD =
new CompassLogData(
(numberOfSingleLineLog +
numberOfmultipleLineLog),
dateTime,
loggingLvl, threadId,
loggingMessage);
//await addRoCompassLogCollectionAsync(cLD);
compassLogCollection.Add(cLD);
} else if (fileName.Contains("CoreService")) {
CoreServiceLogData cSLD =
new CoreServiceLogData(
(numberOfSingleLineLog +
numberOfmultipleLineLog),
dateTime,
loggingLvl,
threadId,
loggingMessage);
//await addRoCoreServiceCollectionAsync(cSLD);
coreServiceLogCollection.Add(cSLD);
} else {
Console.Out.WriteLine("File Not recognizable ");
}
loggingMessage2 = "";
}
}
} catch (Exception e) {
Console.Out.WriteLine("Shit Happens");
Console.Out.WriteLine(e.StackTrace);
}
if (currentFile == "Compass") {
//CompassLogLoadPercent =
// ((double)
// i
// /lines.Count())*100;
CompassLogLoadPercent = ((double)
j
/lines.Count())*100;
} else if (currentFile == "CoreService") {
CoreServiceLogLoadPercent =
((double)
j
/lines.Count())*100;
}
}
});
//}
//compassLogCollection.EnableNotify = true;
//compassLogCollection.notifyAll();
if (currentFile == "Compass") {
Console.Out.WriteLine("Compass TIME: " + swCompass.Elapsed);
} else {
Console.Out.WriteLine("CoreSevice TIME: " + swCompass.Elapsed);
}
if (currentFile == "Compass") {
CompassLogLoadCompleted = true;
Console.Out.WriteLine("Compass LOADING DONE");
} else if (currentFile == "CoreService") {
CoreServiceLogLoadCompleted = true;
Console.Out.WriteLine("CoreService LOADING DONE");
}
//CoreServiceLogLoadCompleted = true;
Console.Out.WriteLine("numberOfSingleLineLog: " +
numberOfSingleLineLog);
Console.Out.WriteLine("numberOfmultipleLineLog: " +
numberOfmultipleLineLog);
Console.Out.WriteLine("numberOfLogs: " +
(numberOfSingleLineLog +
numberOfmultipleLineLog));
Console.Out.WriteLine("");
//}
}
}
but i get the following Exception:
at System.DateTimeParse.Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles)
at System.DateTime.Parse(String s)
at LogViewerV1.LogSession.<>c__DisplayClass3.<LoadLogFile>b__0(Int32 i) in c:\Users\Reza\Documents\Visual Studio 2012\Projects\Pallas informatik\LogViewerV1\LogViewerV1\src\LogSession.cs:line 169
A first chance exception of type 'System.FormatException' occurred in mscorlib.d
If I run this in a ordinary for loop i dont get any exception and everything works fine.
any Idea how to fix This?
FormatException would indicate that the input DateTime is not in the expected format. You should be using the overloads of DateTime.Parse which allow you to specify the DateTypeStyle.
See http://msdn.microsoft.com/en-us/library/system.datetime.parse.aspx#Parse1_Example
I think the problem is that you somehow set the culture of the main thread. But culture is not copied to any other thread, so the background threads that run (parts of) the Parallel.For() loop have different culture.
What you should do is to explicitly specify the culture to use:
DateTime.Parse(dateAndTimestamp, theCorrectCulture)

Categories