Script is a sequence of lines: send EXPR expect EXPR , EXPR await EXPR [, EXPR] on EXPR loop [EXPR] break [EXPR] continue [EXPR] set EXPR = EXPR if EXPR elif EXPR else Lines that are empty, all whitespace, or whose first non-whitespace character is ; or #, are comments. EXPR: IDENT NUMBER STRING ( EXPR ) - EXPR EXPR + EXPR EXPR - EXPR EXPR * EXPR EXPR / EXPR EXPR [ EXPR ] EXPR < EXPR EXPR > EXPR EXPR <= EXPR EXPR >= EXPR EXPR == EXPR EXPR != EXPR EXPR ? EXPR : EXPR [ ] IDENT ( EXPR [, EXPR [,EXPR ...]] ) where IDENT can be: $substr $len IDENT: [A-Za-z_$][A-Za-z0-9_$]* NUMBER: [0-9]+ 0[xX][0-9a-fA-F]+ [0-9]*.[0-9]+ [0-9]+.[0-9]* STRING: " SCHAR* " SCHAR: [ -ÿ] except " or \ \" \\ \a \b \f \n \r \t \OCTAL \xHEX When the first EXPR to expect or on, or the EXPR to loop, break, or continue, is a simple IDENT, it is used for its name rather than its value. (Put parens around it if you want to use a simple variable for its value.) Bodies of on, loop, if/elif/else are indicated by indentation.