Created
June 4, 2020 11:09
-
-
Save kujirahand/53d9ee2ed9ae4b87eaec6b8cae6675ee to your computer and use it in GitHub Desktop.
goyaccの一番簡単なサンプル
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%{ | |
// プログラムのヘッダを指定 | |
package main | |
import ( | |
"os" | |
"fmt" | |
) | |
%} | |
%union { | |
num int | |
} | |
// プログラムの構成要素を指定 | |
%type<num> program expr | |
%token<num> NUMBER | |
// 演算の優先度の指定 | |
%left '+','-' | |
%left '*','/' | |
%% | |
// 文法規則を指定 | |
program | |
: expr | |
{ | |
$$ = $1 | |
yylex.(*Lexer).result = $$ | |
} | |
expr | |
: NUMBER | |
| expr '+' expr { $$ = $1 + $3 } | |
| expr '-' expr { $$ = $1 - $3 } | |
| expr '*' expr { $$ = $1 * $3 } | |
| expr '/' expr { $$ = $1 / $3 } | |
%% | |
// 最低限必要な構造体を定義 | |
type Lexer struct { | |
src string | |
index int | |
result int | |
} | |
// ここでトークン(最小限の要素)を一つずつ返す | |
func (p *Lexer) Lex(lval *yySymType) int { | |
for p.index < len(p.src) { | |
c := p.src[p.index] | |
p.index++ | |
if c == '+' { return int(c) } | |
if c == '-' { return int(c) } | |
if c == '*' { return int(c) } | |
if c == '/' { return int(c) } | |
if '0' <= c && c <= '9' { | |
lval.num = int(c - '0') | |
return NUMBER | |
} | |
} | |
return -1 | |
} | |
// エラー報告用 | |
func (p *Lexer) Error(e string) { | |
fmt.Println("[error] " + e) | |
} | |
// メイン関数 | |
func main() { | |
if len(os.Args) <= 1 { return } | |
lexer := &Lexer{src: os.Args[1], index:0} | |
yyParse(lexer) | |
println("計算結果:", lexer.result) | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment