Vous êtes sur la page 1sur 16

PROGRAM IS TO CALCULATE LEADING FOR ALL THE NON-TERMINALS OF THE GIVEN GRAMMAR Lex - A Lexical Anlyzer Generator #include<conio.

h> #include<stdio.h> char arr[18][3] = { {'E','+','F'},{'E','*','F'},{'E','(','F'},{'E',')','F'},{'E','i','F'},{'E','$','F'}, {'F','+','F'},{'F','*','F'},{'F','(','F'},{'F',')','F'},{'F','i','F'},{'F','$','F'}, {'T','+','F'},{'T','*','F'},{'T','(','F'},{'T',')','F'},{'T','i','F'},{'T','$','F'}, }; char prod[6] = "EETTFF"; char res[6][3]= { {'E','+','T'},{'T','\0'}, {'T','*','F'},{'F','\0'}, {'(','E',')'},{'i','\0'}, }; char stack [5][2]; int top = -1; void install(char pro,char re) { int i; for(i=0;i<18;++i) { if(arr[i][0]==pro && arr[i][1]==re) { arr[i][2] = 'T'; break; } } ++top; stack[top][0]=pro; stack[top][1]=re; } void main() { int i=0,j; char pro,re,pri=' '; clrscr();

for(i=0;i<6;++i) { for(j=0;j<3 && res[i][j]!='\0';++j) { if(res[i][j] =='+'||res[i][j]=='*'||res[i][j]=='('||res[i][j]==')'||res[i][j]=='i'||res[i][j]=='$') { install(prod[i],res[i][j]); break; } } } while(top>=0) { pro = stack[top][0]; re = stack[top][1]; --top; for(i=0;i<6;++i) { if(res[i][0]==pro && res[i][0]!=prod[i]) { install(prod[i],re); } } } for(i=0;i<18;++i) { printf("\n\t"); for(j=0;j<3;++j) printf("%c\t",arr[i][j]); } getch(); clrscr(); printf("\n\n"); for(i=0;i<18;++i) { if(pri!=arr[i][0]) { pri=arr[i][0]; printf("\n\t%c -> ",pri); } if(arr[i][2] =='T') printf("%c ",arr[i][1]); } getch();}

OUTPUT

E E E E E E F F F F F F T T T T T T

+ * ( ) i $ + * ( ) i $ + * ( ) i $

T T T F T F F F T F T F F T T F T F

Below follows a C++ implementation of a table-based LL parser for the example language: #include <iostream> #include <map> #include <stack> enum Symbols { // the symbols: // Terminal symbols: TS_L_PARENS, // ( TS_R_PARENS, // ) TS_A, // a TS_PLUS, // + TS_EOS, // $, in this case corresponds to '\0' TS_INVALID, // invalid token // Non-terminal symbols: NTS_S, // S NTS_F }; /* Converts a valid token to the corresponding terminal symbol */ enum Symbols lexer(char c) { switch(c) { case '(': return TS_L_PARENS; break; case ')': return TS_R_PARENS; break; case 'a': return TS_A; break; case '+': return TS_PLUS; break; case '\0': // this will act as the $ terminal symbol return TS_EOS; break;

default: return TS_INVALID; break; } } int main(int argc, char **argv) { using namespace std; if (argc < 2) { cout << "usage:\n\tll '(a+a)'" << endl; return 0; } // LL parser table, maps < non-terminal, terminal> pair to action map< enum Symbols, map<enum Symbols, int> > table; stack<enum Symbols> ss; // symbol stack char *p; // input buffer // initialize the symbols stack ss.push(TS_EOS); // terminal, $ ss.push(NTS_S); // non-terminal, S // initialize the symbol stream cursor p = &argv[1][0]; // setup the parsing table table[NTS_S][TS_L_PARENS] = 2; table[NTS_S][TS_A] = 1; table[NTS_F][TS_A] = 3; while(ss.size() > 0) { if(lexer(*p) == ss.top()) { cout << "Matched symbols: " << lexer(*p) << endl; p++; ss.pop(); } else { cout << "Rule " << table[ss.top()][lexer(*p)] << endl; switch(table[ss.top()][lexer(*p)]) { case 1: // 1. S F ss.pop(); ss.push(NTS_F); // F break;

case 2: // 2. S ( S + F ) ss.pop(); ss.push(TS_R_PARENS); // ) ss.push(NTS_F); // F ss.push(TS_PLUS); // + ss.push(NTS_S); // S ss.push(TS_L_PARENS); // ( break; case 3: // 3. F a ss.pop(); ss.push(TS_A); break;

// a

default: cout << "parsing table defaulted" << endl; return 0; break; } } } cout << "finished parsing" << endl; return 0; }

1) A Program to Design Lexical Analyzer. #include<string.h> #include<ctype.h> #include<stdio.h>void keyword(char str[10]){if(strcmp("for",str)==0||strcmp("while",str)==0||strcmp("do",str)==0|| strcmp("int",str)==0||strcmp("float",str)==0||strcmp("char",str)==0|| strcmp("double",str)==0||strcmp("static",str)==0||strcmp("switch",str)==0| |strcmp("case",str)==0) printf("\n%s is a keyword",str); else printf("\n%s is an identifier",str); } main() {FILE *f1,*f2,*f3;char c,str[10],st1[10]; int num[100],lineno=0,tokenvalue=0,i=0,j=0,k=0; printf("\nEnter the c program); ;/*gets(st1);*/ f1=fopen("input","w") ;while((c=getchar())!=EOF) putc(c,f1); fclose(f1); f1=fopen("input","r"); f2=fopen("identifier","w"); f3=fopen("specialchar","w"); while((c=getc(f1))!=EOF){if(isdigit(c)) { tokenvalue=c-'0'; c=getc(f1);while(isdigit(c)) { tokenvalue*=10+c-'0';c=getc(f1); }

num[i++]=tokenvalue;ungetc(c,f1); } else if(isalpha(c)) { putc(c,f2);c=getc(f1); while(isdigit(c)||isalpha(c)||c=='_'||c=='$') { putc(c,f2); c=getc(f1); } putc(' ',f2);ungetc(c,f1); } else if(c==' '||c=='\t') printf(" "); else if(c=='\n')lineno++; else putc(c,f3); } fclose(f2) ;fclose(f3); fclose(f1); printf("\nThe no's in the program are); for(j=0;j<i;j++) printf("%d",num[j]); printf("\n"); f2=fopen("identifier","r"); k=0; printf("The keywords and identifiersare:"); while((c=getc(f2))!=EOF) {

if(c!=' ') str[k++]=c; else { str[k]='\0'; keyword(str);k=0; } } fclose(f2); f3=fopen("specialchar","r"); printf("\nSpecial characters are); while((c=getc(f3))!=EOF) printf("%c",c); printf("\n");fclose(f3); printf("Total no. of lines are:%d",lineno); }

Output: Enter the C program a+b*c Ctrl-D The nos in the program are: The keywords and identifiers are: a is an identifier and terminal b is an identifier and terminal c is an identifier and terminal Special characters are: +* Total no. of lines are: 1

The following example shows the contents of the calc.yacc file. This file has entries in all three sections of a yacc grammar file: declarations, rules, and programs. %{ #include <stdio.h> int regs[26]; int base; %} %start list %union { int a; } %type <a> expr number %token DIGIT LETTER %left '|' %left '&' %left '+' '-' %left '*' '/' '%' %left UMINUS %% list: | list stat '\n' | list error '\n' { yyerrok; } ; /*supplies precedence for unary minus */ /* beginning of rules section */ /*empty */

stat:

expr { printf("%d\n",$1); } | LETTER '=' expr {

regs[$1] = $3; } ; expr: '(' expr ')' { $$ = $2; } | expr '*' expr { $$ = $1 * $3; } | expr '/' expr { $$ = $1 / $3; } | expr '%' expr { $$ = $1 % $3; } | expr '+' expr { $$ = $1 + $3; } | expr '-' expr { $$ = $1 - $3; } | expr '&' expr

{ $$ = $1 & $3; } | expr '|' expr { $$ = $1 | $3; } | '-' expr %prec UMINUS { $$ = -$2; } | LETTER { $$ = regs[$1]; }

| number ; number: DIGIT { $$ = $1; base = ($1==0) ? 8 : 10; } |

number DIGIT { $$ = base * $1 + $2; } ;

%%

main() { return(yyparse()); }

yyerror(s) char *s; { fprintf(stderr, "%s\n",s); }

yywrap() { return(1); }

Code for recursive decent parser:


typedef enum {ident, number, lparen, rparen, times, slash, plus, minus, eql, neq, lss, leq, gtr, geq, callsym, beginsym, semicolon, endsym, ifsym, whilesym, becomes, thensym, dosym, constsym, comma, varsym, procsym, period, oddsym} Symbol; Symbol sym; void getsym(void); void error(const char msg[]); void expression(void); int accept(Symbol s) { if (sym == s) { getsym(); return 1; } return 0; } int expect(Symbol s) { if (accept(s)) return 1; error("expect: unexpected symbol"); return 0; } void factor(void) { if (accept(ident)) { ; } else if (accept(number)) { ; } else if (accept(lparen)) { expression(); expect(rparen); } else { error("factor: syntax error"); getsym(); } } void term(void) { factor(); while (sym == times || sym == slash) { getsym(); factor(); } } void expression(void) { if (sym == plus || sym == minus) getsym(); term(); while (sym == plus || sym == minus) { getsym(); term(); } } void condition(void) {

if (accept(oddsym)) { expression(); } else { expression(); if (sym == eql || sym == neq || sym == lss || sym == leq || sym == gtr || sym == geq) { getsym(); expression(); } else { error("condition: invalid operator"); getsym(); } } } void statement(void) { if (accept(ident)) { expect(becomes); expression(); } else if (accept(callsym)) { expect(ident); } else if (accept(beginsym)) { do { statement(); } while (accept(semicolon)); expect(endsym); } else if (accept(ifsym)) { condition(); expect(thensym); statement(); } else if (accept(whilesym)) { condition(); expect(dosym); statement(); } } void block(void) { if (accept(constsym)) { do { expect(ident); expect(eql); expect(number); } while (accept(comma)); expect(semicolon); } if (accept(varsym)) { do { expect(ident); } while (accept(comma)); expect(semicolon); } while (accept(procsym)) { expect(ident); expect(semicolon); block(); expect(semicolon); } statement(); }

void program(void) { getsym(); block(); expect(period); }

Vous aimerez peut-être aussi