zoukankan      html  css  js  c++  java
  • Yacc example on Ubuntu 17.04

    Install Yacc:

    sudo apt install bison
    

     The Yacc input file calc.y:

    %{
    void yyerror(char *s);
    #include<stdio.h> /* c declarations used in actions */
    #include<stdlib.h>
    int symbols[52]; /* symbol table a through z and A through Z */
    int symbolVal(char symbol);
    void updateSymbolVal(char symbol, int val);
    %}
    /* Yacc definitions
     the union lets me specify the different types that my lexical analyzer can return
      integers put in num and characters in id */
    %union{int num; char id;} 
    %start line
    %token print
    %token exit_command
    %token <num> number
    %token <id> identifier
    %type <num> line exp term
    %type <id> assignment
    
    %%
    
    /* descriptions of expected inputs   corresponding actions in c */
    line    : assignment ';'        {;}
            | exit_command ';'      {exit(EXIT_SUCCESS);}
            | print exp ';'         {printf("Printing %d
    ", $2);}
            | line assignment ';'   {;}
            | line print exp ';'    {printf("Printing %d
    ", $3);}
            | line exit_command ';' {exit(EXIT_SUCCESS);}
            ;
    assignment  : identifier '=' exp { updateSymbolVal($1,$3); }
                ;
    exp     : term                  {$$ = $1; }
            | exp '+' term          {$$ = $1 + $3;}
            | exp '-' term          {$$ = $1 - $3;}
            ;
    term    : number                {$$ = $1;}
            | identifier            {$$ = symbolVal($1);}
            ;
    %% /* c code */
    int computeSymbolIndex(char token){
        int idx = -1;
        if(islower(token)){
            idx = token - 'a' + 26; /* the lower case are going to map from 26 to 51 */
        }
        else if(isupper(token)){
            idx = token - 'A';
        }
        return idx;
    }
    /* returns the value of a given symbol */
    int symbolVal(char symbol){
        int bucket = computeSymbolIndex(symbol);
        return symbols[bucket];
    }
    
    /* update the value of a given symbol */
    void updateSymbolVal(char symbol, int val){
        int bucket = computeSymbolIndex(symbol);
        symbols[bucket] = val;
    }
    int main(void){
        /* init symbol table */
        int i;
        for(i=0; i<52; i++){
            symbols[i] = 0;
        }
        return yyparse();//the function generated by yacc
    }
    void yyerror(char *s){fprintf(stderr, "%s
    ",s);}
    

      The lex input file calc.l

    %{
    #include"y.tab.h"
    %}
    
    %%
    "print"         {return print;}
    "exit"          {return exit_command;}
    [a-zA-Z]        {yylval.id = yytext[0]; return identifier;}
    [0-9]+          {yylval.num = atoi(yytext); return number;}
    [ 	
    ]         ;
    [-+=;]          {return yytext[0];}
    .               {ECHO; yyerror ("unexpected character");}
    
    %%
    int yywrap (void) {return 1;}
    

      Commands to generate the interpreter:

    yacc -d calc.y # to generate y.tab.h and y.tab.c is the actual generated parser
    lex calc.l # generates lex.yy.c
    gcc lex.yy.c y.tab.c -o calc
    

      Sample results:

  • 相关阅读:
    【Oracle】子查询、伪列、分页查询、表连接
    【Oracle】dual、sysdate、systimestamp、单行(组)函数、sql执行顺序
    【Oracle】简介、简单查询、去重、排序
    【Java】注解的使用
    【Java】反射机制
    【Java】网络编程(NIO/BIO)
    【Java】枚举
    【Java】File操作
    【Java】多线程
    Hibernate 再接触 关系映射 一对一单向外键关联
  • 原文地址:https://www.cnblogs.com/cxxszz/p/8682801.html
Copyright © 2011-2022 走看看