I am trying to design a server app which will read a command line over a socket stream (one character at a time). Obviously the simple way is to read characters up to the EOL and execute the command contained in the receive buffer.
Instead, I want to have it so that when a user starts entering a command line and then enters "?", the app will generate a list of all the parameters which are syntactically correct from that point in the parsing of the command line (this is similar to the way it is in some embedded devices that I have seen, like Cisco and Netscreen routers).
For example,
$ set interface ?
would display
> set interface [option] -- displays information about the specified interface.
>
> [option] must be one of the following:
> address [ip-addr]
> port [port-no]
> protocol [tcp|udp]
So basically, I would need to know where we were in the grammar, and what symbols are expected from that point forward.
It would also be nice if it could support simple line editing commands (BS, DEL, insert, left-arrow, right-arrow), and maybe even up-arrow/down-arrow for command history.
Can this be done using the boost spirit parser?
EDIT:
Simply put: Is there a simple way to create a boost spirit parser which (in addition to having a set of rules), immediately executes an action anytime '?' is encountered on the input stream (without having to explicitly encode the token '?' into the rules)?
Related
I desesperatly try to find a way to make the application output panel a bit more useful by printing an error with a file path and a line number (basically _ FILE _ and _ LINE _ macros) and make it clickable from the pannel to go directly in the source file in the IDE.
Is it possible to do so with std::cout only ?
I found a post on stack which doesn't work with my need.
The mechanic you need to use here is ANSI escape sequences.
ANSI escape sequences are processed by (mostly) Unix terminals and terminal emulators for changing the terminal behavior, e.g. formatting or coloring text. More recently, hyperlinks may be embedded using an escape sequence as well. For example, the ls utility may embed file:// scheme links with the printed filenames and a terminal may allow to open a file by clicking on it. And GCC does this as well (see -fdiagnostics-urls option).
Several IDEs nowadays also support these links in their output panes. To form a link you need to print one escape sequence before the text and one after (to reset the link state), like so:
printf '\e]8;;http://example.com\e\\This is a link\e]8;;\e\\\n'
Note that \e is ESC, the other characters in the example are regular characters as printed.
Find a good documentation about this, esp. about how to form appropriate file:// URIs here.
For Qt Creator to recognize a link to a source file in the Application Output, it needs to be in a specific format. In my tests I've found the following to work:
std::cout << "file:///home/user/project/src/foo.cpp:1234" << std::endl;
This follows the pattern file://%{file}:%{line}.
Since this question is related to Qt, you may want to set the QT_MESSAGE_PATTERN environment variable such that the file and line number is automatically included in your debug messages. For example:
QT_MESSAGE_PATTERN="%{message} (file://%{file}:%{line})"
For more information, see:
https://doc.qt.io/qt-5/qtglobal.html#qSetMessagePattern
https://doc.qt.io/qt-5/debug.html#warning-and-debugging-messages
I'm working on a project that needs to be run with either of the following commands:
./project.exe -Stack < [filename]
./project.exe -Queue < [filename]
I am wondering why there is a - in front of both Stack and Queue and why the filename is preceded by < and is in brackets.
The purpose of this format is to tell the program to either run using a stack class or run using a queue class. I will also need to extract the information from the text file mentioned in the command line.
I am familiar with general command line arguments and how to use them, but I have never seen this notation before and can't find any clear explanations.
The dash for the options are simply a common convention. Usually with modern command-line programs one uses double-dash for so-called long options (like e.g. --stack) and single dash for short options (e.g. -s).
Many existing argument parsers, like the Linux getopt_long function, actually requires the single or double dashes for short and long options to be recognized as such.
The < is file redirection. It tells the shell to redirect the programs standard input from the file. Inside the program you can read from standard input (std::cin) and it will be automatically reading from the file. This redirection is handled entirely by the shell.
In my parser generated by flex, I would like to be able to store each line in the file, so that when reporting errors, I can show the user the line that the error occurred on.
I could of course do this using a vector and read in all lines from the file before/after lexing, but this would just add to the time needed to parse a file.
What I thought I could instead do, is to store the line whenever a new-line character is matched, and insert the current line into a vector. So my questions is, is there a variable/macro that flex that stores the current line inside? (Something like yyline perhaps)
Note: I am also using bison
By itself, lex/flex does not do what you ask. As noted, you want this for reporting error messages. (I do something like this in vi like emacs).
With lex/flex, the only way to store the entire line is to record each token from the current line into your own line-buffer. That can be complicated, especially if your lexer has to handle multi-line content (such as comments or strings).
The yytext variable only shows you the most recently parsed token (and yylength, the corresponding length). If your lexer does a simple ECHO, that is a token just like the ones you pay attention to.
Reading the file in advance as noted is one way to simplify the problem. In vi like emacs, the lexers read via a function from the in-memory buffer rather than from an input stream. It bypasses the normal stream-handling logic by redefining the YY_INPUT macro, e.g.,
#define YY_INPUT(buf,result,max_size) result = flt_input(buf,max_size)
Likewise, ECHO is redefined (since the editor reads the results back rather than letting them go to the standard output):
#define ECHO flt_echo(yytext, yyleng)
and it traps errors detected by the lexer with another redefinition:
#define YY_FATAL_ERROR(msg) flt_failed(msg);
However you do this, the yylineno value reported for a given token will be at the end of parsing a given token.
While it is nice to report the entire line in context in an error message, it is also useful to track the line and column number of each token -- various editors can deal with lines like this
filename:line:col:message
If you build up your line-buffer by tracking tokens, it might be relatively simple to track the column on which each token begins as well.
I'm pretty new to vim but I'm trying to create some C++ IDE.
I'm used to ctrl f (or ctrl-shift-f) to help me find in files.. so I saw a plugin I liked called pss.
I'd like to replace ctrl-f with something that would accept input but still add parameters of it's own(*.cpp for example)..
I was thinking of something like:
how can I do it correctly?
noremap <C-f>:Pss $1 *.cpp
Since you have editing capabilities in the command-line, a commonly used approach just builds an incomplete mapping. You can position the cursor in the edit location, like this:
:noremap <C-f> :Pss *.cpp<Left><Left><Left><Left><Left><Left>
After triggering the mapping (via <C-f>), you can insert the search pattern, and then trigger the search via <CR>.
Alternative
You can query for input via the input() function; its result can be inserted into the command-line via :execute:
:noremap <C-f> :execute 'Pss' input('Pattern: ') '*.cpp'<CR>
The default search hot-key is faster than the "Ctrl-F", you may type "/" in the normal mode, and continue input with your keywords. Once you need to search in many files, grep is your friend.
I am using a C lexer that is Flex-generated, and a C++ parser that is Bison-generated. I have modified the parser to acccept only string input.
I am calling the parser function yyparse() in a loop, and reading line by line of user input. I stop the loop if the input is "quit".
The problem I am facing is that when input doesn't match any rule, then the parser stops abruptly, and at next iteration starts off at same state, expecting the rule which was stopped (due to syntax error) to complete.
It works fine if the input is valid and matches a parser rule.
On syntax error I have redefined the yyerror() function, that displays a simple error message.
How do I clear the state of the parser when the input doesn't match any parser rule, so that at next iteration the parser starts afresh?
According to my Lex & Yacc book there is a function yyrestart(file) .
Else (and I quote a paragraph of the book:
This means that you cannot restart a lexer just by calling yylex(). You have to reset it into the default state using BEGIN INITIAL, discard any input text buffered up by unput(), and otherwise arrange so that the next call to input() will start reading the new input.
Interesting question - I have a parser that can be compiled with Bison, Byacc, MKS Yacc or Unix Yacc, and I don't do anything special to deal with resetting the grammar whether it fails or succeeds. I don't use a Flex or Lex tokenizer; that is hand-coded, but it works strictly off strings. So, I have to agree with Gamecat; the most likely cause of the trouble is the lexical analyzer, rather than the parser proper.
(If you want to obtain my code, you can download SQLCMD from the IIUG (International Informix User Group) web site. Although the full product requires Informix ESQL/C, the grammar can, in principle, be converted into a standalone test program. Sadly, however, it appears I've not run that test for a while - there are some issues with the test compilation. Some structure element names changed in April 2006, plus there are linkage issues. I will need to re-reorganize the code so that the grammar can be tested standalone again.)