(Connected)
3. Improvement of a function function
In the first two, we have implemented the construction of the top and the following grammar analysis algorithm and the structure of the functional function. In this section, I focused on the operational efficiency and occupying space of the generated function and the occupancy. First investigate the analysis function of the formula E -> T E | T-E | T:
Void e_addsub () {t_muldiv (); // Call the generated function analysis of non-end tutor T T if (CH == ' ' || CH == '-') // If the current character is' 'or' - ', // If it is' ', use the generating E-> T E to derive it, if it is' - ', use the generated E-> TE. {Advance (); // Remove a character e_addsub (); // Call the generation function analysis of non-ender E E} // At this time, the derived algorithm end //// If the next character is not not ' ' or '-', // The function is derived based on generating E-> T, does not have to be incorrectly handled. }
As everyone saw, there is an e_addsub () in the IF statement block; this means that the statement in the E_ADDSUB () function can call yourself, that is, there is recursive in the function. Here, however, we can save a part of the program stack space occupied by recursive occupancy, while also reduces the time spent on the PUSH / POP operation of the program stack. An improved way I want to use here is that the loop replaces the IF by eliminating the return of the recursive depth by eliminating itself, such as the improved E_ADDSUB () function is as follows:
// Listing 7: Analytical functional VOID E_ADDSUB () {t_muldsub () {t_muldsub () {t_muldsub () {t_muldsub () {t_muldsub () {t_muldsub (); // Call the generated function analysis of non-end tutor T while (CH == ' ' || CH == '-') // If the current character is ' ' or '-', // If is ' ', use the generating E-> T E to be derived, // If it is '-', use the generated E-> TE. {Advance (); // Remove a character t_muldiv (); // Call the generated function analysis of non-endue E T} // If the symbol indicated by the current indicator is ' ' or '-', continue While loop // If the next character is not the ' ' or '-', // The function is derived based on generating E-> T, does not have to be incorrectly processed. } We can see that in Listing 7, while turning the if to while, we also change the E_ADDSUB () in the While statement block to t_muldiv (), which means generating the feature (where OP is ' ' or ". - '): E -> T OP E Conversion to: E -> T OP T OP T OP T OP ................ OP T is equivalent. Obviously for the sentences such as I OP I OP I, the latter has a faster derivation speed, while the former needs more 3 recursive stacks. Therefore, the improved generating function is more efficient. Similarly, t_muldiv () can also be improved by this method.
However, this method does not completely eliminate recursive, but reducing the number of recursive calls and cutting the recursive level. Whenever the bracket operator is analyzed, because f_number () is called by t_muldiv (), t_muldiv () is called by e_addsub (), so it generates a recursive function of the generating function of the starter E:
Void f_number () {if (CH == ') // If the current indicator indicated by' ('{//, based on generating f-> (e), Advance (); // Skip '(', The indicator points to the next character e_addsub (); // calls the generated function analysis of the non-ender E E IF (CH! = ')') Error (); // If an error is made, the error is handled. Advance (); // If there is ')', the syntax is correct, skip ')' Return; // Return} ............................................................ Return; // Return}
According to this approach, only one recursive level is increased when analyzing the arithmetic expression in the brace operator, and the efficiency of the grammatical analysis can be effectively improved. 4. Error processing in grammar analysis
Performing error handling maybe a very troublesome thing. Imagine a well-designed compilation debugging environment, such as Visual Studio, when we use it to develop compilers, you can know which sentence is wrong, and you can get an error. What we have to do now is to identify an error for an arithmetic expression (if an error), and prompt the error reason and related information to the user. What should I do?
The textbooks of "Compilation Principles" have been told by examining the method of speaking the FIRST set and the FOLLOW integrated grammatical analysis form, which can populate the wrong processing method into the analysis table. However, since we have constructed a functional functional function, it is simply, so that we can gradually implement an error process by analyzing the Error () function call in the function.
Investigation Listing 5 Middle GB D -> (E) | Void f_number () {if (CH == '(') {Advance (); E_ADDSUB (); if (ch! = ')') / / If the character indicated by the current indicator is not ')', it generates an error, error (); // error number: 1 advance (); return;} if (ch is a number) {advance ();} else // The current indicator indicated that the characters are not numbers, resulting in errors error (); // error number: 2 return;}
In the above code, there are two places that may generate errors in the above code, where the cause of the error is very easy to see, is "right brackets that match the left brackets". The reason for the No. 2 error is "The character indicated by the current indicator is not a number", that is, the number does not appear in the arithmetic expression, such as when the indicator refers to the illegal expression "23 # b". "#", " " And "*" in "*" in "1 - ( " belong to this situation. There are still two cases in the No. 2 error, one is that there is no parentheses Expression (ie, the expression in parentheses is empty), such as "3 ()", which requires determining whether the current indicated characters is ')'; the second is incomplete expression (ie, the expression is in advance), For example, "4 * (2 3) ", this requires determining whether the current indicated characters are '/ 0' (string end compact).
Take another main function in Listing 6: int main () {................................... // The input character buffer and character indicator initialize / / call the starter E analysis function started Top and the following grammatical analysis: e_addsub (); // analysis end ...................................... Return 0;}
However, according to our design, when the E_ADDSUB () function returns (the analysis ends), there may be a character that is not analyzed after the indicator nature, where there is a character that is not scanned by the indicator Expression is incorrect expression. For example, when the indicator refers to "5", "2 3 (4 5)" in illegal expressions "2 3 (4)" ("" and "a" in "23a" It belongs to this error.
(to be continued)