goyaccの一番簡単なサンプル
%{ | |
// プログラムのヘッダを指定 | |
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