What does the following partial lex program do? What does it output?
NW [^A-Za-z']
%start INW NIW
%%
<NIW>"bork"/{NW} ECHO;
<NIW>"Bork"/{NW} ECHO;
The lexer is incomplete:
Nothing switches to the NIW state,
so it doesn't match the two actions where you have ECHO.
That means that
The default rule matches for each input character.
The default rule for lex does an ECHO.
Because every input character is echoed, without changes, the output file is the same as the input.
Related
in my MIRC script, it is set up to read a text file, in these text files there is the symbol " | " followed by a space on both ends, it seems to read everything before " | " just fine, but cuts it off right at the first space. Any help is appreciated.
I am using
msg $nick $read(test.txt, n, 1)
to read the text file.
EDIT:: I have tried all switches which result in the same thing.
EDIT:: It also tells me in the server window "Unknown Command"
EDIT:: After making a new pastebin uploading script, it still seems to get that issue? It will completely just cut off the rest of the text after a "&" or " | "
The symptoms is matching to a scenario which $read was evaluated to a command and the result will take the separators as set of commands to be executed.
This can be due to aliases or events.
Try the first /play command, which will play the file from the 3rd line to see if it behaving as the line we expect it to be or instead each line as a set of commands, separated by /
Then perform the 2nd /play command to view how it should been send to the server.
This is design to see where the problem lie.
/play -axl3 echo test.txt
/play -exl3 test.txt
The output should be the same and as we expect it with the line being displayed including |.
This will make sure the problem is to blame upon other corrupt aliases or events.
We will perform the following and after each step you will test you code to see if it was solved.
Test to see if it an alias named msg hurt you, by converting your script command to /!msg $nick$read(test.txt, n, 1).
Check for dangerous events such as the infamous INPUT or the rising bandit PARSELINE by disabling them.If the problem solved then return the events one by one the find the problematic event and fix it.
Due to the lack of a responses/answers, I was unable to solve it, I have made a makeshift fix for this issue by using
play -xl# $nick test.txt
rather than
msg $nick $read(test.txt, n, 1)
I had almost the same problem and was able to solve it, using the same solution, try this:
Your previous script was: msg $nick $read(test.txt, n, 1)
Now remove the 'msg $nick' and add that to the beginning of every line in the text.txt file with a space between 'msg $nick' and the rest of the line, i.e : msg $nick Hey I see you are back | msg $nick Missed You!
Then your script becomes: $read(test.txt, p)
^^ Hope that makes sense, but I found the original issues was Double Evaluation hence why sometimes you would see the error: Unknown Command or something along those lines.
Here is a sample of a random script in MATLAB.
prompt = 'Please enter a lowercase x: ';
str = input(prompt, 's');
if str == 'x'
else
fprintf('Error, you did not enter a lowercase x.')
end
This always display what I have in the fprintf command with a >> at the end of it in the command window. For example, in this random context it would display ...
Error, you did not enter a lowercase x.>>
Simple question, yet I'm new to MATLAB. Why do I get a >> at the end of every fprintf command? Can't seem to figure it out.
You did not specify a line-break in your string, so fprintf pushes the text to the command windows and spawns another input prompt (the >>) directly after the text. Add a line break meta-character to the string (\n) to fix the issue:
fprintf('Error, you did not enter a lowercase x.\n')
Also, if your goal is to issue an error, you should use the error function. It halts execution of the code and colors the message red like other MATLAB errors.
Here the fprintf simply displays the text and returns to command console.
Use newline '\n' character,
fprintf('Error, you did not enter a lowercase x.\n');
% ~~~
to come back atfer newline with >> prompt
I am using Matlab to print a small text file (temp_script.exec) that will be used to run GrADS commands. The script looks like the following:
'reinit'
'open temp_ctl.ctl'
'set lon -100 -80'
'set lat 20 30'
'define prc = var'
'set sdfwrite data_out.nc'
'sdfwrite prc'
The script is called via cshell:
#!/bin/csh -f
grads -lbc << EOF
temp_script.exec
EOF
exit
The script seems to execute properly, but the output (data_out.nc) is not generated. Strangely, if I edit it using VI and replace the first character -- the single quotation before the command "reinit" -- by typing another single quotation, then re-run the script, data is generated properly.
My question is, what could be different? The scripts look identical in several different text editors, but the "modified" script (by typing) is 1 byte larger. I am using the "fprintf" function to generate the single quotes in Matlab. Could it be some problem with that function?
Thanks for reading.
To see if the files are really the same (the generated one and the one edited with vi):
od -c -t x1 temp_script.exec > temp_script.lis
od -c -t x1 vi_script.exec > vi_script.lis
diff exec_script.lis vi_script.lis
There could be a UNICODE BOM at the beginning of the file, or a missing newline at the end of file that is causing your issue.
I’ve written script that contains numerous hotkeys (general structure is as below). I would like to create another one that when pressed displays a list of all of the hotkeys and their corresponding descriptions that the script contains in a nice, formatted table.
The formatting and display are tenuous since AutoHotkey’s output is limited to message-boxes, but possible. More problematic is getting the hotkeys and corresponding descriptions.
The hotkeys all call the same function with different arguments. I considered adding a variable to the function so that depending on the value, the function either performs the normal function when triggered by the normal hotkeys, or builds a string or something when triggered from the special display hotkey.
I cannot figure out a way to programmatically access the script’s hotkeys at all. I checked the docs and there don’t seem to be any A_ variables that can be used for this purpose, nor does the Hotkey command lend itself well (it can be used to test if a hotkey exists, but looping through the innumerable combinations is, at best, tedious).
Failed attempts:
I tried using Elliot’s suggestion of parsing the script itself (replacing the path with %A_ScriptFullPath%, and while it does work for a raw script, it does not when the script is compiled
I tried assigning the entire hotkey section of the script to a variable as a continuation section and then parsing the variable and creating hotkeys using the Hotkey command. This worked well right up until the last part because the Hotkey command cannot take arbitrary commands as the destination and requires existing labels.
The ListHotkeys command is not applicable because it only displays the hotkeys as plain text in the control window.
Does anyone know how I can display a list of the hotkeys and either their corresponding arguments or comments?
Example script:
SomeFunc(foobar)
{
MsgBox %foobar%
}
!^#A::SomeFunc("a") ; blah
^+NumpadMult::SomeFunc("c") ; blivet
^+!#`::SomeFunc("b") ; baz
^#Space::SomeFunc("d") ; ermahgerd
…
Example desired “outputs”:
C+A+ W+ A a | C+ S+ NumpadMult b
------------------+----------------------
C+A+S+W+ ` c | C+ W+ Space d
or
Ctrl Alt Shift Win Key Action
-----------------------------------------
× × × A blah
× × NumpadMult baz
× × × × ` blivet
× × Space ermahgerd
etc.
The only thing I can think of is to read each line of your script individually and parse it. This code reads your script (script.ahk) one line at a time and parses it. This should get you started. Additionally, you could parse the line to check for the modifiers as well.
Loop
{
FileReadLine, line, C:\script.ahk, %A_Index%
if ErrorLevel
break
If Instr(line, "::")
{
StringSplit, linearray, line, ::,
key := linearray1
StringSplit, commandarray, linearray3, `;
action := commandarray2
hotkeyline := "key: " . key . "`tAction: " . action
final .= hotkeyline . "`r"
}
}
msgbox % final
return
I found a solution. It is not perfect (or ideal), and hopefully a proper, built-in method will become available in the future, but it works well (enough) and for raw and compiled scripts.
What I did was to use the FileInstall command which tells the compiler to add a file to the executable (and extract it when run).
Sadly, the FileInstall command will not allow the use of variables for the source file, so I cannot simply include the script itself (FileInstall, %A_ScriptFullPath%, %A_Temp%\%A_ScriptName%, 1).
As a work-around, I ended up extracting all of the desired hotkeys to a second file which I then parse as Elliot suggested, then delete, and #Include at the end of my script (it must be at the end since hotkeys will terminate the autoexecute section).
;;;;; Test.ahk ;;;;;
; Add hotkey file to executable and extract to Temp directory at runtime
FileInstall, Hotkeys.ahk, %A_Temp%\Hotkeys.ahk, 1
Loop
{
;Read a line from the extracted hotkey script and quit if error
FileReadLine, line, %A_Temp%\Hotkeys.ahk, %A_Index%
if ErrorLevel
break
;Trim whitespace
line=%line%
; Parse the line as in Elliot’s answer, but with tweaks as necessary
ParseHotkey(line)
…
}
FileDelete, %A_Temp%\Hotkeys.ahk ; Delete the extracted script
DisplayHotkeys() ; I ended up bulding and using a GUI instead
#Include, Hotkeys.ahk ; It is included at compile-time, so no A_Temp
;;;;; Hotkeys.ahk ;;;;;
z::MsgBox foo
y::MsgBox bar
I want to use the yy_scan_bytes() as I have null characters defining a rule. My problem is that my string can match more than one rule. I want to get hold of all the rules matched. I want to feed the yylex() function one character at a time and check if something matched. I tried the following code for testing but this doesnt work.
for(int i=0;i<length;i++)
{
yy_scan_bytes(&temp[i],1 );
index=TomsonTalkslex();
}
For simplicity I just return the index of the rule matched from scanner. temp is a char buffer. I tried to use the yy_switch_to_buffer(yy_scan_bytes(&temp[i],1 )); but this didnt work.
How can I tell the scanner not to reset its state and continue processing subsequent buffers with the same state.
Ok, This is just a misunderstanding of how lex/flex works. By default, yylex hooks into stdin, reading until it receives EOF, and matching each rule. That's why it's a tokenizer. So, the sample program below will read from stdin until you enter -c to send an EOF.
%option 8bit outfile="scanner.c"
%option nounput nomain noyywrap
%option warn
%%
ab { fprintf(yyout, "We ran the ab rule.\n"); }
cd { fprintf(yyout, "We ran the cd rule.\n"); }
// echo everything else we find to yyout
. { ECHO; }
\n { ECHO; }
%%
To compile the above, use:
flex -Cf scanner.l
gcc -O -o flexer.exe scanner.c
Save the source file as scanner.l when you do this. Once you compile, you will get a file called flexer.exe in the same directory. Run it from a terminal, and you will get a blank prompt waiting for input. Everything you type will try and match against the rules, until you find only one match. It will then execute the code associated with the rule.
Therefore, if you type abcd, then you will match both the ab and cd rules.
I suggest reading lex and yacc for a more detailed introduction.