This question already has an answer here:
"Fun" C++ library that interprets ASCII figures in code - what is it called? ("Multi-Dimensional Analog Literals")
(1 answer)
Closed 9 years ago.
If I recall correctly, I saw some ungodly C++ library that let you type ASCII-art shapes in C++ programs and treat them as objects. Something like this:
int area = someFreakyClass(o-----o
| |
o-----o).area();
What was this library called?
Analog Literals by Eelis.
Improved version of Analog Literals:
Tweaking Analog Literals (C++ humor)
Something like this:
int area = someFreakyClass(_________________________________________________
/| | |
|| | |
.----|-----,| |
|| || ==|| |
.-----'--'| ==|| |
|)- ~| ||_________________________________________________|
| ___ | |____...==..._ >\______________________________|
[_/.-.\"--"-------- //.-. .-.\\/ |/ \\ .-. .-. //
( o )`==="""""""""`( o )( o ) o `( o )( o )`
'-' '-' '-' '-' '-').area();
Related
Hello we have this antlr4 Tree Parser:
grammar calc;
calculator: (d)*;
c
: c '*' c
| c '/' c
| c '+' c
| c '-' c
| '(' c ')'
| '-'?
| ID
;
d: ID '=' c;
NBR: [0-9]+;
ID: [a-zA-Z][a-zA-Z0-9]*;
WS: [ \t\r\n]+ -> skip;
The Problem is if I use a -, antlr4 doesn´t recognize, if is it ja sign or operator for sepcial inputs like: (-2-4)*4. For Inputs like this antlr4 doesn´t understand that the - befor the 2 belongs to the constant 2 and that the - is not a operator.
Just do something like this:
c
: '-' c
| c ('*' | '/') c
| c ('+' | '-') c
| '(' c ')'
| ID
| NBR
;
That way all these will be OK:
-1
- 2
-3-4
5+-6
-(7*8)
(-2-4)*4
For example, (-3-10)*10 is parsed like this:
EDIT
This is what happens when I parse 9+38*(19+489*243/1)*1+3:
| '-'?
should be:
| '-'? NBR
You need to specify that it's a NBR that may (or may not) be preceded by a -
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I know what puts and gets do, but I don't understand the meaning of this code.
int main(void) {
char s[20];
gets(s); //Helloworld
gets(s+2);//dog
sort(s+1,s+7);
puts(s+4);
}
Could you please help me to understand?
Draw it on paper, along these lines.
At first, twenty uninitialised elements:
| | | | | | | | | | | | | | | | | | | | |
gets(s):
|H|e|l|l|o|w|o|r|l|d|0| | | | | | | | | |
gets(s+2):
|H|e|d|o|g|0|o|r|l|d|0| | | | | | | | | |
^
|
s+2
sort(s+1, s+7):
|H|0|d|e|g|o|o|r|l|d|0| | | | | | | | | |
^ ^
| |
s+1 s+7
puts(s+4):
|H|0|d|e|g|o|o|r|l|d|0| | | | | | | | | |
^
|
s+4
The best thing to say about the code is that it is very bad. Luckily, it is short but it is vulnerable, unmaintainable and error prone.
However, since the previous is not really an answer, let's go through the code, assuming the standard include files were used and "using namespace std;":
char s[20];
This declares an array of 20 characters with the intent of filling it with a null-terminated string. If somehow, the string becomes larger, you're in trouble
gets(s); //Helloworld
This reads in a string from stdin. No checks can be done on the size. The comment assumes it will read in Helloworld, which should fit in s.
gets(s+2);//dog
This reads in a second string from stdin, but it will overwrite the previous string starting from the third character. So if the comment is write, s will contain the null-terminated string "Hedog".
sort(s+1,s+7);
This will sort the characters in asserting ascii value from the second up to the seventh character. With the given input, we already have a problem that the null-character is on the sixth position so it will be part of the sorted characters and thus will be second, so the null-terminated string will be "H".
puts(s+4);
Writes out the string from the fifth position on, so until the null-charater that was read in for "Helloworld", but then overwritten and half-sorted. Of course input can be anything, so expect surprises.
gets(s); //Helloworld -- reads a string from keyboard to s
gets(s+2);//dog -- reads a string from keyboard to s started with char 2
sort(s+1,s+7); -- sorts s in interval [1, 7]
puts(s+4); -- writes to console s from char 4
gets(s); //Helloworld --> s=Helloworld
gets(s+2);//dog --> s=Hedog
sort(s+1,s+7); --> s=Hdego
puts(s+4); --> console=Hdego
This question already has answers here:
What does int argc, char *argv[] mean?
(12 answers)
Closed 6 years ago.
What I understand is argc holds total number of arguments. Suppose my program takes 1 argument apart from program name. Now what does argv hold? Two pointer eg: 123,130 or ./hello\0 and 5. If it holds 123 how does it know it has read one argument? Does it know because of \0.
If all the above is wrong, can someone help me understand using memory map.
The argv array is an array of strings (where each entry in the array is of type char*). Each of those char* arrays is, itself, NUL-terminated. The argv array, itself, does not need to end in NULL (which is why a separate argc variable is used to track the length of the argv array).
In terms of those arrays being constructed to begin with, this is dependent on the calling program. Typically, the calling program is a shell program (such as BASH), where arguments are separated via whitespace (with various quoting options available to allow arguments to include whitespace). Regardless of how the argc, argv parameters are constructed, the operating system provides routines for executing a program with this as the program inputs (e.g. on UNIX, that method is one of the various variations of exec, often paired with a call to fork).
To make this a bit more concrete, suppose you ran:
./myprog "arg"
Here is an example of how this might look in memory (using completely fake addresses):
Addresss | Value | Comment
========================
0058 | 2 | argc
0060 | 02100 | argv (value is the memory address of "argv[0]")
...
02100 | 02116 | argv[0] (value is the memory address of "argv[0][0]")
02104 | 02300 | argv[1] (value is the memory address of "argv[1][0]")
...
02116 | '.' | argv[0][0]
02117 | '/' | argv[0][1]
02118 | 'm' | argv[0][2]
02119 | 'y' | argv[0][3]
02120 | 'p' | argv[0][4]
02121 | 'r' | argv[0][5]
02122 | 'o' | argv[0][6]
02123 | 'g' | argv[0][7]
02124 | '\0' | argv[0][8]
...
02300 | 'a' | argv[1][0]
02301 | 'r' | argv[1][1]
02302 | 'g' | argv[1][2]
02303 | '\0' | argv[1][3]
SML/NJ provides a series of non-standard features, such as higher-order modules, vector literal syntax, etc.
Is there a way to disable these non-standard features in SML/NJ, through some command-line param maybe, or, ideally, using a CM directive?
Just by looking at the grammar used by the parser, I'm going to say that there is not a way to do this. From "admin/base/compiler/Parse/parse/ml.grm":
apat' : OP ident (VarPat [varSymbol ident])
| ID DOT qid (VarPat (strSymbol ID :: qid varSymbol))
| int (IntPat int)
| WORD (WordPat WORD)
| STRING (StringPat STRING)
| CHAR (CharPat CHAR)
| WILD (WildPat)
| LBRACKET RBRACKET (ListPat nil)
| LBRACKET pat_list RBRACKET (ListPat pat_list)
| VECTORSTART RBRACKET (VectorPat nil)
| VECTORSTART pat_list RBRACKET (VectorPat pat_list)
| LBRACE RBRACE (unitPat)
| LBRACE plabels RBRACE (let val (d,f) = plabels
in RecordPat{def=d,flexibility=f}
end)
The VectorPat stuff is fully mixed in with the rest of the patterns. A recursive grep for VectorPat also will show that there aren't any options to turn this off anywhere else.
What options do I have to find any string from a list in another string ?
With s being an std::string, I tried
s.find("CAT" || "DOG" || "COW" || "MOUSE", 0);
I want to find the first one of these strings and get its place in the string ; so if s was "My cat is sleeping\n" I'd get 3 as return value.
boost::to_upper(s);
was applied (for those wondering).
You can do this with a regex.
I don't think there's a way to get the position of a match directly, so first you have to search for the regex, and if there is a match you can search for that string. Like this:
#include <iostream>
#include <string>
#include <regex>
using namespace std;
int main() {
string s = "My cat is sleeping\n";
smatch m;
regex animal("cat|dog|cow|mouse");
if (regex_search (s,m,animal)) {
cout << "Match found: " << m.str() << endl;
size_t match_position = s.find(m.str());
// In this case it is always true, but in general you might want to check
if (match_position != string::npos) {
cout << "First animal found at: " << match_position << endl;
}
}
return 0;
}
You may convert your search cases to a DFA. It is the most efficient way of doing it.
states:
nil, c, ca, cat., d, do, dog., co, cow., m, mo, mou, mous, mouse.
transition table:
state | on | goto
nil | c | c
nil | d | d
nil | m | m
c | a | ca
c | o | co
d | o | do
m | o | mo
ca | t | cat.
co | w | cow.
do | g | dog.
mo | u | mou
mou | s | mous
mous | e | mouse.
* | * | nil
You may express this using a lot of intermediary functions. Using a lot of switches. Or using enum to represent states and a mapping to represent the transitions.
If your test case list is dynamic or grows too big, then a manually hardcoding the states will nor suffice for you. However, as you can see, the rule to make the states and the transitions is very simple.