================================= Storage Classes extern and static [TOC] ================================= ---- VIDEO ------------------------------ https://www.youtube.com/embed/5BFV85znXyQ ----------------------------------------- Exercise: Lexer for the _abc_ Compiler ====================================== We have to apply some improvements to our compiler project that we started in __Session 13, Page 4__: - The lexer should also give as information about the line number and column in which a token was found. It should also be possible to retrieve the current token directly. And yes, we use here global variables declared in a header (in the end only _lexer.h_ will declare a global variable, and just one). The header was therefore modified as follows (we clearly need _struct_ and _enum_ soon): :import: session14/abc/lexer.h - This is the modified test program. Just a line of code was added to also print the token position: :import: session14/abc/xtest_lexer.c - In _lexer.c_ all functions and global variables that are not declared in the header should be declared as static. ---- BOX ----------------------------------------------------------------------- *Of course the real deal here is:* Change the implementation in _lexer.c_ so that after calling _getToken()_ the values of the global variables declared in ~lexer.h~ are correct. -------------------------------------------------------------------------------- Some Example ------------ You can use a file like this to test you lexer: ---- CODE (file=test_lexter.in) ------------------------------------------------ a = 5; b = 42; c = (a + b) *2; 123 0123 0xaB12 abc +-/*%^() -------------------------------------------------------------------------------- Then with ~xtest_test~ you should get: ---- CODE (type=txt) ----------------------------------------------------------- theon$ ./xtest_lexer < test_lexer.in 1.1: IDENTIFIER 1.3: EQUAL 1.5: DEC_LITERAL 1.6: SEMICOLON 2.1: IDENTIFIER 2.3: EQUAL 2.5: DEC_LITERAL 2.7: SEMICOLON 3.1: IDENTIFIER 3.3: EQUAL 3.5: LPAREN 3.6: IDENTIFIER 3.8: PLUS 3.10: IDENTIFIER 3.11: RPAREN 3.13: ASTERISK 3.14: DEC_LITERAL 3.15: SEMICOLON 4.1: DEC_LITERAL 4.5: OCT_LITERAL 4.10: HEX_LITERAL 4.17: IDENTIFIER 4.21: PLUS 4.22: MINUS 4.23: SLASH 4.24: ASTERISK 4.25: PERCENT 4.26: BAD_TOKEN 4.27: LPAREN 4.28: RPAREN -------------------------------------------------------------------------------- Once we double checked that the lexer is handling lines and columns correctly we can save the output in a file: ---- CODE (type=txt) ----------------------------------------------------------- theon$ ./xtest_lexer < test_lexer.in > test_lexer.ref.out -------------------------------------------------------------------------------- Later we can use in the makefile a target _check_ so that _make check_ simply comares in furture the result with this trusted output. Basically this target will do in this case a _diff_: ---- CODE (type=txt) ----------------------------------------------------------- theon$ ./xtest_lexer < test_lexer.in > test_lexer.out theon$ diff test_lexer.out test_lexer.ref.out -------------------------------------------------------------------------------- :links: Session 13, Page 4 -> doc:session13/page04