forked from wa-lang/wa
106 lines
1.3 KiB
Plaintext
106 lines
1.3 KiB
Plaintext
// 版权 @2023 凹语言 作者。保留所有权利。
|
|
|
|
%{
|
|
// 这是 凹语言 yacc 的例子, 用于对表达式进行解析, 为了简化词法部分暂时通过手工录入.
|
|
%}
|
|
|
|
%union {
|
|
num int
|
|
}
|
|
|
|
%type <num> expr expr1 expr2 expr3
|
|
|
|
%token '+' '-' '*' '/' '(' ')'
|
|
|
|
%token <num> NUM
|
|
|
|
%%
|
|
|
|
top:
|
|
expr {
|
|
println($1)
|
|
}
|
|
|
|
expr:
|
|
expr1
|
|
| '+' expr {
|
|
$$ = $2
|
|
}
|
|
| '-' expr {
|
|
$$ = -$2
|
|
}
|
|
|
|
expr1:
|
|
expr2
|
|
| expr1 '+' expr2 {
|
|
$$ = $1 + $3
|
|
}
|
|
| expr1 '-' expr2 {
|
|
$$ = $1 - $3
|
|
}
|
|
|
|
expr2:
|
|
expr3
|
|
| expr2 '*' expr3 {
|
|
$$ = $1 * $3
|
|
}
|
|
| expr2 '/' expr3 {
|
|
$$ = $1 / $3
|
|
}
|
|
|
|
expr3:
|
|
NUM
|
|
| '(' expr ')' {
|
|
$$ = $2
|
|
}
|
|
|
|
|
|
%%
|
|
|
|
// Lex 结束标志
|
|
const eof = 0
|
|
|
|
type exprToken struct {
|
|
Kind int
|
|
Value int
|
|
}
|
|
|
|
type exprLexer struct {
|
|
tokens []exprToken
|
|
pos int
|
|
}
|
|
|
|
func (p *exprLexer) Lex(yylval *exprSymType) int {
|
|
if p.pos >= len(p.tokens) {
|
|
return eof
|
|
}
|
|
tok := p.tokens[p.pos]
|
|
p.pos++
|
|
|
|
yylval.num = tok.Value
|
|
return tok.Kind
|
|
}
|
|
|
|
func (x *exprLexer) Error(s string) {
|
|
println("ERROR:", s)
|
|
}
|
|
|
|
func main() {
|
|
print("1+2*(3+4)-10 = ")
|
|
exprParse(&exprLexer{
|
|
tokens: []exprToken{
|
|
{Kind: NUM, Value: 1},
|
|
{Kind: '+'},
|
|
{Kind: NUM, Value: 2},
|
|
{Kind: '*'},
|
|
{Kind: '('},
|
|
{Kind: NUM, Value: 3},
|
|
{Kind: '+'},
|
|
{Kind: NUM, Value: 4},
|
|
{Kind: ')'},
|
|
{Kind: '-'},
|
|
{Kind: NUM, Value: 10},
|
|
},
|
|
})
|
|
}
|