Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- %{
- #include <stdio.h> /* printf() */
- #include <string.h> /* strcpy */
- #include <stdlib.h> /* atoi(), atof() */
- #include "common.h" /* MAX_STR_LEN */
- #include "p.tab.h" /* declaration of terminal symbols */
- int process_token(const char *text, const char *TokenType,
- const char *TokenVal, const int TokenID);
- int comm_beg = 0; /* starting line of a comment */
- int text_beg = 0; /* starting line of a string */
- int yylineno;
- %}
- alpha [a-zA-Z]
- num [0-9]
- alphanum [a-zA-Z0-9]
- alphanum2 [a-zA-Z0-9_]
- /* declaraction of additional start conditions */
- /* (INITIAL start condition does not need to be declared) */
- /* ..................... */
- %x ST_STRING_CONST ST_COMMENT_1 ST_COMMENT_2
- %option yylineno
- %%
- /* removal of multiline comments (*..*) */
- /* using start conditions */
- /* ..................... */
- <INITIAL>\(\* { BEGIN ST_COMMENT_1; comm_beg = yylineno;}
- <ST_COMMENT_1>\*\) BEGIN INITIAL;
- <ST_COMMENT_1>.|\n ;
- /* removal of multiline comments {..} */
- /* z using start conditions */
- /* ..................... */
- <INITIAL>\{ { BEGIN ST_COMMENT_2; comm_beg = yylineno; }
- <ST_COMMENT_2>\} BEGIN INITIAL;
- <ST_COMMENT_2>.|\n ;
- /* detecting an error: Unexpected closing of comment in the line */
- /* ..................... */
- <INITIAL>\}|(\*\)) printf("Unexpected closing of comment in the line %d\n", yylineno);
- /* detecting strings '..' */
- /* using start conditions */
- <INITIAL>\' { BEGIN ST_STRING_CONST; yymore(); text_beg = yylineno;}
- <ST_STRING_CONST>\' { BEGIN INITIAL; return process_token(yytext, "STRING_CONST", yytext, STRING_CONST);}
- <ST_STRING_CONST>. yymore();
- /* not using start conditions */
- /* (\'.*\') return process_token(yytext, "STRING_CONST", yytext, STRING_CONST); */
- /* detection of directives in form of {$I name.ext} */
- /* (without start conditions) */
- /* ..................... */
- \{$I\ .+\} printf("Parsing include direcive\n");
- /* Detection of keywords (case-insensitive)! */
- /* ..................... */
- (?i:PROGRAM) return process_token(yytext, "KW_PROGRAM", "", KW_PROGRAM);
- (?i:BEGIN) return process_token(yytext, "KW_BEGIN", "", KW_BEGIN);
- (?i:END) return process_token(yytext, "KW_END", "", KW_END);
- (?i:USES) return process_token(yytext, "KW_USES", "", KW_USES);
- (?i:VAR) return process_token(yytext, "KW_VAR", "", KW_VAR);
- (?i:CONST) return process_token(yytext, "KW_CONST", "", KW_CONST);
- (?i:IF) return process_token(yytext, "KW_IF", "", KW_IF);
- (?i:THEN) return process_token(yytext, "KW_THEN", "", KW_THEN);
- (?i:CHAR) return process_token(yytext, "KW_CHAR", "", KW_CHAR);
- (?i:INTEGER) return process_token(yytext, "KW_INTEGER", "", KW_INTEGER);
- (?i:REAL) return process_token(yytext, "KW_REAL", "", KW_REAL);
- (?i:FOR) return process_token(yytext, "KW_FOR", "", KW_FOR);
- (?i:TO) return process_token(yytext, "KW_TO", "", KW_TO);
- (?i:DO) return process_token(yytext, "KW_DO", "", KW_DO);
- (?i:FUNCTION) return process_token(yytext, "KW_FUNCTION", "", KW_FUNCTION);
- (?i:PROCEDURE) return process_token(yytext, "KW_PROCEDURE", "", KW_PROCEDURE);
- (?i:DOWNTO) return process_token(yytext, "KW_DOWNTO", "", KW_DOWNTO);
- (?i:ARRAY) return process_token(yytext, "KW_ARRAY", "", KW_ARRAY);
- (?i:RECORD) return process_token(yytext, "KW_RECORD", "", KW_RECORD);
- (?i:OF) return process_token(yytext, "KW_OF", "", KW_OF);
- /* detecting terminal symbols specified with regular expressions */
- /* identifiers */
- [A-Za-z_]{alphanum2}* return process_token(yytext, "IDENT", yytext, IDENT);
- /* intergers */
- {num}+ return process_token(yytext, "INTEGER_CONST", yytext, INTEGER_CONST);
- /* real numbers */
- ({num}*\.{num}+)|({num}+\.) return process_token(yytext, "FLOAT_CONST", yytext, FLOAT_CONST);
- /* cutting out whitespace */
- [ \n\t] ;
- /* multicharacter expressions, e.g.: :=, <= */
- \:\= return process_token(yytext, "ASSIGN", "", ASSIGN);
- \<\= return process_token(yytext, "LE", "", LE);
- /* one character operators and punctuation */
- [+\-*;,=:.(){}\[\]] return process_token(yytext, yytext, "", *yytext);
- %%
- /* Name: strnncpy
- * Purpose: Copies given number of characters from a stream appending
- * character with code 0.
- * Parameters: dst - (o) string to be copied from;
- * src - (i) string to be copied to;
- * n - (i) max number of characters to copy.
- * Returns: dst.
- * Remarks: strncpy does not append character 0 to the copied string.
- * Destination string must have room for additional n+1 character.
- */
- char *
- strnncpy(char *dst, const char *src, const int n)
- {
- if (n > 0) {
- strncpy(dst, src, n);
- }
- dst[n] = '\0';
- return dst;
- }/*strnncpy*/
- /* Name: process_token
- * Purpose: Print information about detected token and pass it up
- * with its value if present.
- * Parameters: text - (i) matched text;
- * TokenType - (i) string representing token name;
- * TokenVal - (i) token value if present;
- * TokenID - (i) token type identifier declared
- * using %token directive
- * in c.y file single character code
- * (in the parser put into single quotes).
- * Returns: Token type identifier (TokenID).
- * Remarks: Info about detected token is printed in 3 columns.
- * The first one contains matched text, the second - token type,
- * the third - token value, if it exists.
- */
- int process_token(const char *text, const char *TokenType,
- const char *TokenVal, const int TokenID)
- {
- int l;
- printf("%-20.20s%-15s %s\n", text, TokenType, TokenVal);
- switch (TokenID) {
- case INTEGER_CONST:
- yylval.i = atoi(TokenVal); break;
- case FLOAT_CONST:
- yylval.d = atof(TokenVal); break;
- case IDENT:
- strncpy(yylval.s, TokenVal, MAX_STR_LEN); break;
- case STRING_CONST: /* rozpoznany napis zawiera cudzysłowy */
- l = strlen(TokenVal);
- strnncpy(yylval.s, TokenVal+1, l - 2 <= MAX_STR_LEN ? l - 1 : MAX_STR_LEN);
- break;
- case CHARACTER_CONST:
- yylval.i = TokenVal[1]; break;
- }
- return(TokenID);
- }/*process_token*/
- int yywrap( void )
- { /* function called at the end of input stream */
- /* Checking whether the current start condition YY_START */
- /* is different from INITIAL. If so, */
- /* it means unclosed comment or string - */
- /* print error message.*/
- /* ..................... */
- if (YYSTATE != INITIAL){
- if (comm_beg < text_beg)
- printf("Unclosed string in the line %d", text_beg);
- else printf("Unclosed comment in the line %d", comm_beg);
- }
- return( 1 ); /* needed to prevent restart of the analysis */
- }
Add Comment
Please, Sign In to add comment