LoginSignup
0
0

More than 5 years have passed since last update.

きつねさんとLLVMで作った電卓を追証してみた

Last updated at Posted at 2018-09-02

msys2で更の状態からLLVMの環境を構築する。

  1. msys2-x86_64-20180531.exe を使ってC:\msys64にインストールします。
  2. pacman -S mingw-w64-x86_64-clang で、clangとついでにLLVMを入れます。
  3. 環境変数のパスに、C:\msys64\usr\bin;C:\msys64\mingw\binを追加します。
  4. flexは入っていたので、pacman -S bison でbisonを入れます。
  5. makeが入ってないので、pacman -S make でmakeを入れます。
  6. きつねさんとLLVMで作った電卓の、calc.lとcalc.yからコメントを消します。
  7. bisonなので、y.tab.でなくcalc.tab.で書き換えます。
  8. Makefileを書き換えます。
  9. GOROOT=C:\msys64\mingw64\lib\goとGOPATH=C:\msys64\mingw64\lib\goを適切に設定しないと、エラーで動かない場合があります。

calc.l

%{
#include <stdio.h>              
#include "calc.tab.h"           /* "calc.tab.h"はbisonコマンド実行時に出力されます。 */
int yywrap(void) { return 1; }  
%}

%%

"+" return OPERATOR_ADD;
"-" return OPERATOR_SUB;
"*" return OPERATOR_MUL;
"/" return OPERATOR_DIV;
"\n" return EOL;

[1-9][0-9]* {
    double temp_box;
    sscanf(yytext, "%lf", &temp_box);
    yylval.double_value = temp_box;
    return DOUBLE_LITERAL;
}
"0" {
    yylval.double_value = 0.0;
    return DOUBLE_LITERAL;
}

[0-9]*\.[0-9]* {
    double temp_box;
    sscanf(yytext, "%lf", &temp_box);
    yylval.double_value = temp_box;
    return DOUBLE_LITERAL;
}

%%

calc.y

%{
#include <stdio.h>
#include <stdlib.h>
%}

%union {
    double double_value;
}

%token  <int_value> INT_LITERAL   
%token  <double_value>  DOUBLE_LITERAL 
%token      OPERATOR_ADD 
            OPERATOR_SUB 
            OPERATOR_MUL 
            OPERATOR_DIV
            EOL          

%type   <double_value>  expression term primary_expression

%%

source_code
: line
| source_code line
;

line
: expression EOL
{
    printf(">> %lf\n", $1);
}
;

expression
: term
| expression OPERATOR_ADD term
{
    $$ = $1 + $3;
}
| expression OPERATOR_SUB term
{
    $$ = $1 - $3;
}
;

term
: primary_expression
| term OPERATOR_MUL primary_expression
{
    $$ = $1 * $3;
}
| term OPERATOR_DIV primary_expression
{
    $$ = $1 / $3;
}
;

primary_expression
: DOUBLE_LITERAL
;
%%

int yyerror(char const* str)
{
    extern char *yytext;
    fprintf(stderr, "Error near %s\n", yytext);
    return 0;
}

int main(void)
{
    extern int yyparse(void);  
    extern FILE *yyin;         

    yyin = stdin;              
        if (yyparse()) {
        fprintf(stderr, "ERROR!\n");
        exit(1);
    }
    return 0;
}

Makefile

CC      := clang

all:    calc

calc:   calc.tab.c lex.yy.c 
    $(CC) -o calc.exe calc.tab.c lex.yy.c

calc.tab.c: calc.y
    bison -d calc.y 

lex.yy.c:   calc.l 
    flex calc.l 

clean: 
    rm calc.tab.*
    rm lex.yy.c
    rm calc.exe 

参考

言語を作る!bisonとflexを使ってみた

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0