0
votes

I developed for my university a mini-shell. For parse the command line I use lex and yacc.

When I press up/down/left/right arrow the string "^[[A or B or C or D is displayed.

Is it possible to recognize this character for execute action when this key is pressed ? Maybe using the functions of ncurses library (I'm in Linux)?

I show, the bash use yacc grammar ( https://en.wikipedia.org/wiki/GNU_bison ) and we can use the arrow key. So I think is possible.

Thank you.

1
The handling of arrow keys etc is wholly separate from Lex or Yacc. It involves working with terminal modes (raw and cooked), which is something that ncurses does handle — or you may want to look at the GNU Readline library (which is closer to what is used by Bash, I believe). Note that different terminal types send different character sequences for up-arrow; you may need some of the facilities from termcap or terminfo to handle the terminal dependencies.Jonathan Leffler
Keys are behavioral items, not lexical/grammatical items. To put it another way, your shell's scanner translates input that it receives into tokens, and your shell's grammar then uses those tokens to evaluate an expression. Arrow keys don't generate input unless you change terminal modes as explained by Jonathan Leffler, so your scanner won't receive them as input.user539810
You can embed readlink within your program, or simply install rlwrap and run rlwrap ./my-mini-shell to get the behavior without any change.Rudi

1 Answers

4
votes

You could...

Essentially, yacc provides you with a state machine using terminal tokens (symbolic constants) provided by lex. Think of it as a big switch statement.

The arrow-keys returned by curses (if you call keypad) are defined in the curses header file as symbolic constants, e.g., KEY_UP, KEY_HOME, etc. There's a list in the getch manual page.

The curses library reads the character sequences, using its own state machine, matches the sequences against the terminal description and returns the constants.

Whether you get constants from lex or curses doesn't really matter much. yacc doesn't care. Also, whether you even use lex in this case, or just call getch directly may not matter (depending on how you have organized your program).

But most people wouldn't bother with lex/yacc for parsing editing sequences on the input buffer.