aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2015-01-08 18:18:33 +0100
committerDimitri Sokolyuk <demon@dim13.org>2015-01-08 18:18:33 +0100
commit40aa6de8a706ac88a7451dad0058c59f26bd9a7f (patch)
tree6bfd1bd81e96757dea3f0947ab1e1926adde0422
parent14ad206ae26716c619661c221b8c56c6627fbb3e (diff)
Replace runes with named tokens
-rw-r--r--calc.y51
-rw-r--r--lexer.go22
2 files changed, 47 insertions, 26 deletions
diff --git a/calc.y b/calc.y
index 202d4ca..2801690 100644
--- a/calc.y
+++ b/calc.y
@@ -30,12 +30,13 @@ var ireg = make(map[rune]Interval)
%token <rval> DREG VREG
%token <dval> NUMBER
%token <sval> STRING
+%token EQ LBR RBR COM
%type <dval> dexp
%type <vval> vexp
-%left '+' '-'
-%left '*' '/'
+%left SUM SUB
+%left MUL DIV
%left UMINUS
%%
@@ -43,25 +44,25 @@ var ireg = make(map[rune]Interval)
line
: dexp { fmt.Println($1) }
| vexp { fmt.Println($1) }
- | DREG '=' dexp { $3.Set($1) }
- | VREG '=' vexp { $3.Set($1) }
+ | DREG EQ dexp { $3.Set($1) }
+ | VREG EQ vexp { $3.Set($1) }
| STRING { fmt.Println($1) }
;
dexp
: NUMBER
| DREG { $$.Get($1) }
- | dexp '+' dexp { $$ = $1 + $3 }
- | dexp '-' dexp { $$ = $1 - $3 }
- | dexp '*' dexp { $$ = $1 * $3 }
- | dexp '/' dexp { $$ = $1 / $3 }
- | '-' dexp %prec UMINUS { $$ = -$2 }
- | '(' dexp ')' { $$ = $2 }
+ | dexp SUM dexp { $$ = $1 + $3 }
+ | dexp SUB dexp { $$ = $1 - $3 }
+ | dexp MUL dexp { $$ = $1 * $3 }
+ | dexp DIV dexp { $$ = $1 / $3 }
+ | SUB dexp %prec UMINUS { $$ = -$2 }
+ | LBR dexp RBR { $$ = $2 }
| error { $$ = Number(math.NaN()) }
;
vexp
- : '(' dexp ',' dexp ')' {
+ : LBR dexp COM dexp RBR {
if $2 > $4 {
$$ = Interval{$4, $2}
} else {
@@ -69,35 +70,35 @@ vexp
}
}
| VREG { $$.Get($1) }
- | vexp '+' vexp { $$ = $3.vadd($1) }
- | dexp '+' vexp { $$ = $3.vadd(Interval{$1, $1}) }
- | vexp '+' dexp { $$ = Interval{$3, $3}.vadd($1) }
- | vexp '-' vexp { $$ = $3.vsub($1) }
- | dexp '-' vexp { $$ = $3.vsub(Interval{$1, $1}) }
- | vexp '-' dexp { $$ = Interval{$3, $3}.vsub($1) }
- | vexp '*' vexp { $$ = $3.vmul($1) }
- | dexp '*' vexp { $$ = $3.vmul(Interval{$1, $1}) }
- | vexp '*' dexp { $$ = Interval{$3, $3}.vmul($1) }
- | vexp '/' vexp {
+ | vexp SUM vexp { $$ = $3.vadd($1) }
+ | dexp SUM vexp { $$ = $3.vadd(Interval{$1, $1}) }
+ | vexp SUM dexp { $$ = Interval{$3, $3}.vadd($1) }
+ | vexp SUB vexp { $$ = $3.vsub($1) }
+ | dexp SUB vexp { $$ = $3.vsub(Interval{$1, $1}) }
+ | vexp SUB dexp { $$ = Interval{$3, $3}.vsub($1) }
+ | vexp MUL vexp { $$ = $3.vmul($1) }
+ | dexp MUL vexp { $$ = $3.vmul(Interval{$1, $1}) }
+ | vexp MUL dexp { $$ = Interval{$3, $3}.vmul($1) }
+ | vexp DIV vexp {
if $3.dcheck() {
yylex.Error("divisor interval contains 0")
}
$$ = $3.vdiv($1)
}
- | dexp '/' vexp {
+ | dexp DIV vexp {
if $3.dcheck() {
yylex.Error("divisor interval contains 0")
}
$$ = $3.vdiv(Interval{$1, $1})
}
- | vexp '/' dexp {
+ | vexp DIV dexp {
if $3 == 0 {
yylex.Error("divisor interval contains 0")
}
$$ = Interval{$3, $3}.vdiv($1)
}
- | '-' vexp %prec UMINUS { $$ = $2.vneg() }
- | '(' vexp ')' { $$ = $2 }
+ | SUB vexp %prec UMINUS { $$ = $2.vneg() }
+ | LBR vexp RBR { $$ = $2 }
;
%%
diff --git a/lexer.go b/lexer.go
index 9049cbd..b059625 100644
--- a/lexer.go
+++ b/lexer.go
@@ -15,8 +15,23 @@ const (
upper
quoted
char
+ sum
+ sub
+ mul
+ div
)
+var charmap = map[rune]int {
+ '+': SUM,
+ '-': SUB,
+ '*': MUL,
+ '/': DIV,
+ '=': EQ,
+ '(': LBR,
+ ')': RBR,
+ ',': COM,
+}
+
type item struct {
typ int
val string
@@ -54,7 +69,12 @@ func (y *yyLex) Lex(lval *yySymType) int {
lval.sval = item.val[1:len(item.val)-1]
return STRING
case char:
- return int(item.val[0])
+ c := rune(item.val[0])
+ if ch, ok := charmap[c]; ok {
+ return ch
+ } else {
+ return int(c)
+ }
}
return eof
}