商用
%{ /* * line numbering 1 */ int lineno = 1 % \n { lineno++ ECHO ^.*$ printf("%d\t%s", lineno, yytext)
$ lex ln1.l $ gcc -o ln1 lex.yy.c -ll day := (1461*y) div 4 + (153*m+2) div 5 + d if a then c := 1 while (c) do c := c - 1 $./ln1 < data.p 1 day := (1461*y) div 4 + (153*m+2) div 5 + d 3 if a then c := 1 5 while (c) 6 do c := c - 1
%{ /* * line numbering 2 */ int lineno = 0 % ^.*\n printf("%d\t%s", ++lineno, yytext) 1 day := (1461*y) div 4 + (153*m+2) div 5 + d 2 3 if a then c := 1 4 5 while (c) 6 do c := c - 1 %{ /* * word count */ int nchar, nword, nline % \n ++nchar, ++nline [^ \t\n]+ ++nword, nchar += yyleng. ++nchar
int main(void) { yylex() printf("%d\t%d\t%d\n", nchar, nword, nline) return 0 92 25 6
$ wc data.p 6 25 92 data.p %{ #include <stdio.h> #include <ctype.h> % %token DIGIT line : expr '\n' { putchar('\n') expr : expr '+' term { putchar('+') expr '-' term { putchar('-') term term : DIGIT { printf("%d", yylval) int yylex() { int c while (1) { c = getchar() if (c == ' ' c == '\t') else if (isdigit(c)) {
yylval = c - '0' return DIGIT else return c int main() { if (yyparse() == 0) printf("!\n\n") else printf("!\n\n")
$ yacc in2po-rec1.y $ gcc -o in2po-rec1 y.tab.c -ly $./in2po-rec1 9-5+2 95-2+! %{ #include <stdio.h> #include <ctype.h> % %token DIGIT line : expr '\n' { putchar('\n') expr : expr '+' term { putchar('+') expr '-' term { putchar('-') term term : DIGIT { printf("%d", yylval)
int main() { if (yyparse() == 0) printf("!\n\n") else printf("!\n\n") %{ #include "in2po-rec2.tab.h" % [ \t]+ [0-9] { yylval = yytext[0] - '0' return DIGIT [+\-\n] return yytext[0] #endif #define DIGIT 258 #if! defined (YYSTYPE) &&! defined (YYSTYPE_IS_DECLARED) typedef int YYSTYPE
$ lex in2po-rec2.l $ bison -d in2po-rec2.y $ gcc -o in2po-rec2 lex.yy.c in2po-rec2.tab.c -ll -ly $./in2po-rec2 9-5+2 95-2+! %{ #include <stdio.h>
#include <ctype.h> % %token DIGIT line : expr '\n' { printf("%d\n", $1) expr : expr '+' term { $$ = $1 + $3 expr '-' term { $$ = $1 - $3 term term : DIGIT { $$ = $1 int yylex() { int c while (1) { c = getchar() if (c == ' ' c == '\t') else if (isdigit(c)) { yylval = c - '0' return DIGIT else return c int main() { if (yyparse() == 0) printf("!\n\n") else printf("!\n\n")
$ yacc calc.y $ gcc -o calc y.tab.c -ly $./calc 9-5+2 6! day := (1461*y) div 4 + (153*m+2) div 5 + d if a then c := 1 while (c) do c := c - 1 %{ /* * */ #include <string.h> #include "y.tab.h" %
delim [ \t\n] ws {delim+ letter [A-Za-z] digit [0-9] id {letter({letter {digit)* number {digit+(\.{digit+)?(e[+\-]?{digit+)? {ws ":=" return(assign) div return(div) mod return(mod) if return(if) then return(then) while return(while) do return(do) {id { strcpy(yylval.lexeme, yytext) return(id) {number { strcpy(yylval.lexeme, yytext) return(num). return(yytext[0]) %{ /* * */
#include <stdio.h> #include <string.h> char *tmp_lbl1, *tmp_lbl2 % %union { char lexeme[10] %start list %token ID NUM DIV MOD ASSIGN IF THEN WHILE DO list : list '' stmt stmt stmt : ID ASSIGN { printf("\tlvalue\t%s\n", $1.lexeme) expr { printf("\t:=\n") IF expr { tmp_lbl1 = new_lbl_no() printf("\tgofalse\t%s\n", tmp_lbl1) THEN stmt { printf("label\t%s\n", tmp_lbl1) WHILE { tmp_lbl1 = new_lbl_no() printf("label\t%s\n", tmp_lbl1) expr { tmp_lbl2 = new_lbl_no() printf("\tgofalse\t%s\n", tmp_lbl2) DO stmt { printf("\tgoto\t%s\n", tmp_lbl1) printf("label\t%s\n", tmp_lbl2) expr : expr '+' term { printf("\t+\n") expr '-' term { printf("\t-\n") term term : term '*' factor { printf("\t*\n") term '/' factor { printf("\t/\n") term DIV factor { printf("\tdiv\n") term MOD factor { printf("\tmod\n")
factor factor : '(' expr ')' ID { printf("\trvalue\t%s\n", $1.lexeme) NUM { printf("\tpush\t%s\n", $1.lexeme) char* new_lbl_no(void) { static int lbl_no = 0 char buf[4] int i, quot char *lbl_header lbl_header = (char *)malloc(5) strcpy(lbl_header, "lbl_") buf[3] = '\0' quot = lbl_no++ for (i = 2 - (quot / 10) i >= 0 i--) { buf[i] = '0' + quot % 10 quot = quot / 10 return((char *)strcat(lbl_header, buf)) int main(void) { printf("\ncompilation for Abstract Stack Machine Started...\n\n") printf("\nassembly code for Abstract Stack Machine follows...\n\n") if (yyparse() == 0) printf("\n\ncompilation for Abstract Stack Machine Completed!\n") else printf("\n\ncompilation for Abstract Stack Machine Failed!\n") $ lex stack-m.l $ yacc -d stack-m.y $ gcc -o stack-m lex.yy.c y.tab.c -ll -ly
./stack-m < data.p > data.asm Compilation for Abstract Stack Machine Started... Assembly code for Abstract Stack Machine follows... label label label lvalue day push 1461 rvalue y * push 4 div push 153 rvalue m * push 2 + push 5 div + rvalue d + := rvalue a gofalse lbl_000 lvalue c push 1 := lbl_000 lbl_001 rvalue c gofalse lbl_002 lvalue c rvalue c push 1 - := goto lbl_001 lbl_002
Compilation for Abstract Stack Machine Completed!