Is it possible to parse fixed width content?
I sketched the following, but it does not compile:
grammar FixedWidth;
content: name age birthday;
name: character[10, false];
age: integer[2, false];
birthday: date['yyyy-MM-dd', true];
salary: float[9, 2, true];
character[int n, boolean required] locals [int i=1]:
({$required && $i == 1}? NONBLANKCHAR {!$required && $i == 1}? CHAR {$i < $n}? CHAR {$i++;});
integer[int n, boolean required] locals [int i=1]: ({$i <= $n}? INT {$required}? | SPACE {$i++;});
float[int n, int decimals, boolean required] locals [int i=1]: ({$i < $n}? INT {$i == $n - $decimals - 1}? '.' {$i++;});
date[String dateFormat, boolean required] locals [int i=1;int n = $dateFormat.length();String mask = $dateFormat.replace('y', $INT).replace('M', $INT).replace('d', $INT)]: ($mask {!$required}? | String.format("%" + $n + "s", "")) ;
NONBLANKCHAR: ~[SPACE] ;
CHAR: [.] ;
INT: [0-9] ;
SPACE: ' ' ;
Forgive me in case of any dumb error above. I am newbie to g4.
Related
Trying to create a simple caesar cipher ... It fails to work on all characters i.e {,},& etc. How can I modify my code to accomodate all characters possible including Chinese characters
String caesar(String text, int key, int encrypt) {
String result = "";
for (var i = 0; i < text.length; i++) {
int ch = text.codeUnitAt(i), offset, x;
if (ch >= 'a'.codeUnitAt(0) && ch <= 'z'.codeUnitAt(0))
offset = 97;
else if (ch >= 'A'.codeUnitAt(0) && ch <= 'Z'.codeUnitAt(0))
offset = 65;
else if (ch == ' '.codeUnitAt(0)) {
result += " ";
continue;
}
if (encrypt == 1)
x = (ch + key - offset) % 26;
else
x = (ch - key - offset) % 26;
result += String.fromCharCode(x + offset);
}
return result;
}
You'd need to create an alphabet, consisting of a string of all possible characters, and replace 26 with the size of that alphabet (the ABC is just one Western oriented alphabet). Then you can use the zero-based index in the alphabet instead of ch - offset for each character.
You cannot use the same trick with the comparison with A and Z as the code points are not a continuous string of printable characters. That means that adding the key may result in a non-existent or unprintable character value. You could create two methods: toIndex(codeUnit) and toCodeUnit(index) so you can perform any calculation you wish though.
I presume you have enough characters within the normal Chinese character range. If you want to use rare Chinese characters that have a code point higher than 0xFFFF then you may have another problem to solve.
Try it! This only works in english.
import 'dart:io';
// the preset alphabet
List<String> alphabet = [
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z'
];
void main() {
stdout.write("Enter the Caesar key: ");
// if the entered k is null, then set k as 0
var k = int.parse(stdin.readLineSync() ?? "0");
stdout.write("Enter the plaintext: ");
// not including the uppercase
var plaintext = (stdin.readLineSync() ?? "").toLowerCase();
var ciphertext = "";
for (var char in plaintext.split('')) {
// if the char is a letter, then match the alphabet
if (char.contains(RegExp(r'[a-z]'))) {
for (var i = 0; i < 26; i++) {
if (alphabet[i] == char) {
// if the matched letter is 26-k below, then find the letter over k interval
if (i < 26 - k) {
ciphertext += alphabet[i + k];
} else {
// if above, return the start point
ciphertext += alphabet[i + k - 26];
}
}
}
} else {
// if not, then simply add it
ciphertext += char;
}
}
print("The ciphertext is: $ciphertext");
}
I reviewed these lines of codes which used to convert string to binary, but i cant understand what this
line of code is doing (hexchar_to_int(str[i]) << 4) | hexchar_to_int(str[i+1]), i am frustrated
with this bit manipulation here, 8 bit of unsigned int used and we shifted left to get the least 4
significant bits. But i don't know the purpose of doing so.
unsigned char hexchar_to_int(char const ch)
{
if (ch >= '0' && ch <= '9') return ch - '0';
if (ch >= 'A' && ch <= 'F') return ch - 'A' + 10;
if (ch >= 'a' && ch <= 'f') return ch - 'a' + 10;
throw std::invalid_argument("Invalid hexadecimal character");
}
std::vector<unsigned char> hexstr_to_bytes(std::string_view str)
{
std::vector<unsigned char> result;
for (size_t i = 0; i < str.size(); i += 2)
{
result.push_back((hexchar_to_int(str[i]) << 4) | hexchar_to_int(str[i+1]));
}
return result;
}
<<4 is *2^4 or *16, shifting left, not right.
The | is a simple addition of the 2 hexa characters at their correct place.
See 0xab = 10*16 + 11 = 171
Im trying to make a toString method that prints out a histogram that shows how often each character of the alphabet is used in a string. The most frequent character has to be 60 #s long, with the rest of the characters then scaled to match.
My issue is with making the equation that scales the rest of the letters to the correct length for the histogram. My current equation is (myArray[i]/max) * 60, but im getting really weird results.
If I put in "hello world" to be analyzed, L would be the most common occuring letter, seen 3 times. So L should have 60 #s for the histogram, h should have 20, o should have 40 etc. Instead im getting results like d : 10
e : 10
h : 10
l : 360
o : 20
r : 10
w : 10
Sorry for how sloppy this is right now, im just trying to figure out whats going on
public class LetterCounter
private static int[] alphabetArray;
private static String input;
/**
* Constructor for objects of class LetterCounter
*/
public LetterCounter()
{
alphabetArray = new int[26];
}
public void countLetters(String input) {
this.input = input;
this.input.toLowerCase();
//String s= input;
//s.toLowerCase();
for ( int i = 0; i < input.length(); i++ ) {
char ch= input.charAt(i);
if (ch >= 97 && ch <= 122){
alphabetArray[ch-'a']++;
}
}
}
public void getTotalCount() {
for (int i = 0; i < alphabetArray.length; i++) {
if(alphabetArray[i]>=0){
char ch = (char) (i+97);
System.out.println(ch +" : "+alphabetArray[i]);
}
}
}
public void reset() {
for (int i =0; i<alphabetArray.length; i++) {
if(alphabetArray[i]>=0){
alphabetArray[i]=0;
char ch = (char) (i+97);
System.out.println(ch +" : "+alphabetArray[i]);
}
}
}
public String toString() {
String s = "";
int max = alphabetArray[0];
int markCounter = 0;
for(int i =0; i<alphabetArray.length; i++) {
//finds the largest number of occurences for any letter in the string
if(alphabetArray[i] > max) {
max = alphabetArray[i];
}
}
for(int i =0; i<alphabetArray.length; i++) {
//trying to scale the rest of the characters down here
if(alphabetArray[i] > 0) {
markCounter = (alphabetArray[i] / max) * 60;
char ch = (char) (i+97);
System.out.println(ch +" : "+alphabetArray[i] + markCounter);
}
}
for (int i = 0; i < alphabetArray.length; i++) {
//prints the whole alphabet, total number of occurences for all chars
if(alphabetArray[i]>=0){
char ch = (char) (i+97);
System.out.println(ch +" : "+alphabetArray[i]);
}
}
return s;
}
}
There are many many problems with your code, but lets go one by one.
First of all, your print statement is simply misleading. Change it to
System.out.println(ch +" : "+alphabetArray[i] + " " + markCounter);
and you will see
d : 1 0
e : 1 0
h : 1 0
l : 3 60
o : 2 0
r : 1 0
w : 1 0
As you can see: the counters are correct (1,1,1,3,2,1,1). But the your scaling doesn't work:
1 / 3 --> 0 ... and 0 * 3 ... is still 0
3 / 3 --> 1 and 1 * 3 ... is 60
but of course, when you dont print a space between 1 and 0 and 3 and 60.
Thus to get correct scaling, just change to:
markCounter = alphabetArray[i] * 60 / max;
Other things worth mentioning:
You are overriding toString(). Then you should put #Override in fron t of that method
toLowerCase() returns a new string in lower case; just calling it without pushing the result back into your string ... just throws away the "lower casing".
toString() shouldnt print to the console. The whole idea is that you put all the information into the string that you return. In other words: in the end you do some System.out.println(someLetterCounter.toString()
Your code is extremely low-level. You don't iterate arrays using for (int), you can do (int letter : alphabetArray) instead
You might want to read about Map. You see, if you would be using a Map<Character, Integer> where the map key would represent the different characters, and the map value represents a counter for each character ... well, you could throw out most of your code; and come up with a solution that would require a few lines of code only!
( and seriously: because of all these issues, debugging your code was really much harder than it needed to be )
countLetters seems has some issues. You can not convert String to lowercase by just calling
this.input.toLowerCase();
Because String is immutable in java. You have to assign it like:
this.input = input.toLowerCase();
Another problem is you are using input variable from parameter instead of this.input which has lower case string. You can do this way to make work countLetters method:
public void countLetters(String input) {
this.input = input.toLowerCase();
for ( int i = 0; i < this.input.length(); i++ ) {
char ch= this.input.charAt(i);
if (ch >= 97 && ch <= 122) {
alphabetArray[ch-'a']++;
}
}
}
to_expr function leads to error. Could you advise what is wrong below?
context z3_cont;
expr x = z3_cont.int_const("x");
expr y = z3_cont.int_const("y");
expr ge = ((y==3) && (x==2));
ge = swap_tree( ge );
where swap_tree is a function that shall swap all operands of binary operations. It defined as follows.
expr swap_tree( expr e ) {
Z3_ast ee[2];
if ( e.is_app() && e.num_args() == 2) {
for ( int i = 0; i < 2; ++i ) {
ee[ 1 - i ] = swap_tree( e.arg(i) );
}
for ( int i = 0; i < 2; ++i ) {
cout <<" ee[" << i << "] : " << to_expr( z3_cont, ee[ i ] ) << endl;
}
return to_expr( z3_cont, Z3_update_term( z3_cont, e, 2, ee ) );
}
else
return e;
}
The problem is "referencing counting". A Z3 object can be garbage collected by the system if its reference counter is 0. The Z3 C++ API provides "smart pointers" (expr, sort, ...) for automatically managing the reference counters for us. Your code uses Z3_ast ee[2]. In the for-loop, you store the result of swap_tree(e.arg(0)) into ee[0]. Since the reference counter is not incremented, this Z3 object may be deleted when executing the second iteration of the loop.
Here is a possible fix:
expr swap_tree( expr e ) {
if ( e.is_app() && e.num_args() == 2) {
// using smart-pointers to store the intermediate results.
expr ee0(z3_cont), ee1(z3_cont);
ee0 = swap_tree( e.arg(0) );
ee1 = swap_tree( e.arg(1) );
Z3_ast ee[2] = { ee1, ee0 };
return to_expr( z3_cont, Z3_update_term( z3_cont, e, 2, ee ) );
}
else {
return e;
}
}
I want to remove all spaces from a string in Lua. This is what I have tried:
string.gsub(str, "", "")
string.gsub(str, "% ", "")
string.gsub(str, "%s*", "")
This does not seem to work. How can I remove all of the spaces?
It works, you just have to assign the actual result/return value. Use one of the following variations:
str = str:gsub("%s+", "")
str = string.gsub(str, "%s+", "")
I use %s+ as there's no point in replacing an empty match (i.e. there's no space). This just doesn't make any sense, so I look for at least one space character (using the + quantifier).
You use the following function :
function all_trim(s)
return s:match"^%s*(.*)":match"(.-)%s*$"
end
Or shorter :
function all_trim(s)
return s:match( "^%s*(.-)%s*$" )
end
usage:
str=" aa "
print(all_trim(str) .. "e")
Output is:
aae
The fastest way is to use trim.so compiled from trim.c:
/* trim.c - based on http://lua-users.org/lists/lua-l/2009-12/msg00951.html
from Sean Conner */
#include <stddef.h>
#include <ctype.h>
#include <lua.h>
#include <lauxlib.h>
int trim(lua_State *L)
{
const char *front;
const char *end;
size_t size;
front = luaL_checklstring(L,1,&size);
end = &front[size - 1];
for ( ; size && isspace(*front) ; size-- , front++)
;
for ( ; size && isspace(*end) ; size-- , end--)
;
lua_pushlstring(L,front,(size_t)(end - front) + 1);
return 1;
}
int luaopen_trim(lua_State *L)
{
lua_register(L,"trim",trim);
return 0;
}
compile something like:
gcc -shared -fpic -O -I/usr/local/include/luajit-2.1 trim.c -o trim.so
More detailed (with comparison to the other methods): http://lua-users.org/wiki/StringTrim
Usage:
local trim15 = require("trim")--at begin of the file
local tr = trim(" a z z z z z ")--anywhere at code
For LuaJIT all methods from Lua wiki (except for, possibly, native C/C++) were awfully slow in my tests. This implementation showed the best performance:
function trim (str)
if str == '' then
return str
else
local startPos = 1
local endPos = #str
while (startPos < endPos and str:byte(startPos) <= 32) do
startPos = startPos + 1
end
if startPos >= endPos then
return ''
else
while (endPos > 0 and str:byte(endPos) <= 32) do
endPos = endPos - 1
end
return str:sub(startPos, endPos)
end
end
end -- .function trim
If anyone is looking to remove all spaces in a bunch of strings, and remove spaces in the middle of the string, this this works for me:
function noSpace(str)
local normalisedString = string.gsub(str, "%s+", "")
return normalisedString
end
test = "te st"
print(noSpace(test))
Might be that there is an easier way though, I'm no expert!