Start conditions provide greater sensitivity to prior context than is afforded by the ^ operator alone. You might want to apply different rules to an expression depending on a prior context that is more complex than the end of a line or the start of a file.
In this situation you could set a flag to mark the change in context that is the condition for the application of a rule, then write code to test the flag. Alternatively, you could define for lex the different ``start conditions'' under which it is to apply each rule.
Consider this problem:
Copy the input to the output, except change the word magic to the word first on every line that begins with the letter a.
Change magic to second on every line that begins with b.
Change magic to third on every line that begins with c. Here is how the problem might be handled with a flag.
Recall that ECHO is a lex macro equivalent to printf("%s", yytext):
int flag %% ^a {flag = 'a'; ECHO;} ^b {flag = 'b'; ECHO;} ^c {flag = 'c'; ECHO;} \n {flag = 0; ECHO;} magic { switch (flag) { case 'a': printf("first"); break; case 'b': printf("second"); break; case 'c': printf("third"); break; default: ECHO; break; } }
To handle the same problem with start conditions, each start condition must be introduced to lex in the definitions section with a line, such as the following one, where the conditions can be named in any order:
%Start name1 name2 ...
The word Start can be abbreviated to S or s. The conditions are referenced at the head of a rule with <> brackets. So the following is a rule that is recognized only when the scanner is in start condition name1:
<name1>expression
To enter a start condition, execute the action following statement:
BEGIN name1;
The above statement changes the start condition to name1. To resume the normal state, use the following:
BEGIN 0;
This resets the initial condition of the scanner.
A rule can be active in several start conditions. For example, the following is a legal prefix:
<name1,name2,name3>
Any rule not beginning with the <> prefix operators is always active.
The example can be written with start conditions as follows:
%Start AA BB CC %% ^a {ECHO; BEGIN AA;} ^b {ECHO; BEGIN BB;} ^c {ECHO; BEGIN CC;} \n {ECHO; BEGIN 0;} <AA>magic printf("first"); <BB>magic printf("second"); <CC>magic printf("third");