Skip to content

Instantly share code, notes, and snippets.

@kujirahand
Created June 4, 2020 11:09
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kujirahand/53d9ee2ed9ae4b87eaec6b8cae6675ee to your computer and use it in GitHub Desktop.
Save kujirahand/53d9ee2ed9ae4b87eaec6b8cae6675ee to your computer and use it in GitHub Desktop.
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