| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613 |
- //line expr.y:13
- package main
- import __yyfmt__ "fmt"
- //line expr.y:14
- import (
- "bufio"
- "bytes"
- "fmt"
- "io"
- "log"
- "math/big"
- "os"
- "unicode/utf8"
- )
- //line expr.y:29
- type exprSymType struct {
- yys int
- num *big.Rat
- }
- const NUM = 57346
- var exprToknames = [...]string{
- "$end",
- "error",
- "$unk",
- "'+'",
- "'-'",
- "'*'",
- "'/'",
- "'('",
- "')'",
- "NUM",
- }
- var exprStatenames = [...]string{}
- const exprEofCode = 1
- const exprErrCode = 2
- const exprInitialStackSize = 16
- //line expr.y:92
- // The parser expects the lexer to return 0 on EOF. Give it a name
- // for clarity.
- const eof = 0
- // The parser uses the type <prefix>Lex as a lexer. It must provide
- // the methods Lex(*<prefix>SymType) int and Error(string).
- type exprLex struct {
- line []byte
- peek rune
- }
- // The parser calls this method to get each new token. This
- // implementation returns operators and NUM.
- func (x *exprLex) Lex(yylval *exprSymType) int {
- for {
- c := x.next()
- switch c {
- case eof:
- return eof
- case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
- return x.num(c, yylval)
- case '+', '-', '*', '/', '(', ')':
- return int(c)
- // Recognize Unicode multiplication and division
- // symbols, returning what the parser expects.
- case '×':
- return '*'
- case '÷':
- return '/'
- case ' ', '\t', '\n', '\r':
- default:
- log.Printf("unrecognized character %q", c)
- }
- }
- }
- // Lex a number.
- func (x *exprLex) num(c rune, yylval *exprSymType) int {
- add := func(b *bytes.Buffer, c rune) {
- if _, err := b.WriteRune(c); err != nil {
- log.Fatalf("WriteRune: %s", err)
- }
- }
- var b bytes.Buffer
- add(&b, c)
- L:
- for {
- c = x.next()
- switch c {
- case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', 'e', 'E':
- add(&b, c)
- default:
- break L
- }
- }
- if c != eof {
- x.peek = c
- }
- yylval.num = &big.Rat{}
- _, ok := yylval.num.SetString(b.String())
- if !ok {
- log.Printf("bad number %q", b.String())
- return eof
- }
- return NUM
- }
- // Return the next rune for the lexer.
- func (x *exprLex) next() rune {
- if x.peek != eof {
- r := x.peek
- x.peek = eof
- return r
- }
- if len(x.line) == 0 {
- return eof
- }
- c, size := utf8.DecodeRune(x.line)
- x.line = x.line[size:]
- if c == utf8.RuneError && size == 1 {
- log.Print("invalid utf8")
- return x.next()
- }
- return c
- }
- // The parser calls this method on a parse error.
- func (x *exprLex) Error(s string) {
- log.Printf("parse error: %s", s)
- }
- func main() {
- in := bufio.NewReader(os.Stdin)
- for {
- if _, err := os.Stdout.WriteString("> "); err != nil {
- log.Fatalf("WriteString: %s", err)
- }
- line, err := in.ReadBytes('\n')
- if err == io.EOF {
- return
- }
- if err != nil {
- log.Fatalf("ReadBytes: %s", err)
- }
- exprParse(&exprLex{line: line})
- }
- }
- //line yacctab:1
- var exprExca = [...]int{
- -1, 1,
- 1, -1,
- -2, 0,
- }
- const exprPrivate = 57344
- const exprLast = 23
- var exprAct = [...]int{
- 7, 4, 5, 2, 21, 9, 6, 8, 12, 13,
- 9, 1, 8, 16, 3, 19, 20, 17, 18, 14,
- 15, 10, 11,
- }
- var exprPact = [...]int{
- -3, -1000, -1000, 17, -3, -3, 13, -1000, -1000, -3,
- 2, 2, -1000, -1000, 2, 2, -5, 13, 13, -1000,
- -1000, -1000,
- }
- var exprPgo = [...]int{
- 0, 3, 14, 6, 0, 11,
- }
- var exprR1 = [...]int{
- 0, 5, 1, 1, 1, 2, 2, 2, 3, 3,
- 3, 4, 4,
- }
- var exprR2 = [...]int{
- 0, 1, 1, 2, 2, 1, 3, 3, 1, 3,
- 3, 1, 3,
- }
- var exprChk = [...]int{
- -1000, -5, -1, -2, 4, 5, -3, -4, 10, 8,
- 4, 5, -1, -1, 6, 7, -1, -3, -3, -4,
- -4, 9,
- }
- var exprDef = [...]int{
- 0, -2, 1, 2, 0, 0, 5, 8, 11, 0,
- 0, 0, 3, 4, 0, 0, 0, 6, 7, 9,
- 10, 12,
- }
- var exprTok1 = [...]int{
- 1, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 8, 9, 6, 4, 3, 5, 3, 7,
- }
- var exprTok2 = [...]int{
- 2, 3, 10,
- }
- var exprTok3 = [...]int{
- 0,
- }
- var exprErrorMessages = [...]struct {
- state int
- token int
- msg string
- }{}
- //line yaccpar:1
- /* parser for yacc output */
- var (
- exprDebug = 0
- exprErrorVerbose = false
- )
- type exprLexer interface {
- Lex(lval *exprSymType) int
- Error(s string)
- }
- type exprParser interface {
- Parse(exprLexer) int
- Lookahead() int
- }
- type exprParserImpl struct {
- lval exprSymType
- stack [exprInitialStackSize]exprSymType
- char int
- }
- func (p *exprParserImpl) Lookahead() int {
- return p.char
- }
- func exprNewParser() exprParser {
- return &exprParserImpl{}
- }
- const exprFlag = -1000
- func exprTokname(c int) string {
- if c >= 1 && c-1 < len(exprToknames) {
- if exprToknames[c-1] != "" {
- return exprToknames[c-1]
- }
- }
- return __yyfmt__.Sprintf("tok-%v", c)
- }
- func exprStatname(s int) string {
- if s >= 0 && s < len(exprStatenames) {
- if exprStatenames[s] != "" {
- return exprStatenames[s]
- }
- }
- return __yyfmt__.Sprintf("state-%v", s)
- }
- func exprErrorMessage(state, lookAhead int) string {
- const TOKSTART = 4
- if !exprErrorVerbose {
- return "syntax error"
- }
- for _, e := range exprErrorMessages {
- if e.state == state && e.token == lookAhead {
- return "syntax error: " + e.msg
- }
- }
- res := "syntax error: unexpected " + exprTokname(lookAhead)
- // To match Bison, suggest at most four expected tokens.
- expected := make([]int, 0, 4)
- // Look for shiftable tokens.
- base := exprPact[state]
- for tok := TOKSTART; tok-1 < len(exprToknames); tok++ {
- if n := base + tok; n >= 0 && n < exprLast && exprChk[exprAct[n]] == tok {
- if len(expected) == cap(expected) {
- return res
- }
- expected = append(expected, tok)
- }
- }
- if exprDef[state] == -2 {
- i := 0
- for exprExca[i] != -1 || exprExca[i+1] != state {
- i += 2
- }
- // Look for tokens that we accept or reduce.
- for i += 2; exprExca[i] >= 0; i += 2 {
- tok := exprExca[i]
- if tok < TOKSTART || exprExca[i+1] == 0 {
- continue
- }
- if len(expected) == cap(expected) {
- return res
- }
- expected = append(expected, tok)
- }
- // If the default action is to accept or reduce, give up.
- if exprExca[i+1] != 0 {
- return res
- }
- }
- for i, tok := range expected {
- if i == 0 {
- res += ", expecting "
- } else {
- res += " or "
- }
- res += exprTokname(tok)
- }
- return res
- }
- func exprlex1(lex exprLexer, lval *exprSymType) (char, token int) {
- token = 0
- char = lex.Lex(lval)
- if char <= 0 {
- token = exprTok1[0]
- goto out
- }
- if char < len(exprTok1) {
- token = exprTok1[char]
- goto out
- }
- if char >= exprPrivate {
- if char < exprPrivate+len(exprTok2) {
- token = exprTok2[char-exprPrivate]
- goto out
- }
- }
- for i := 0; i < len(exprTok3); i += 2 {
- token = exprTok3[i+0]
- if token == char {
- token = exprTok3[i+1]
- goto out
- }
- }
- out:
- if token == 0 {
- token = exprTok2[1] /* unknown char */
- }
- if exprDebug >= 3 {
- __yyfmt__.Printf("lex %s(%d)\n", exprTokname(token), uint(char))
- }
- return char, token
- }
- func exprParse(exprlex exprLexer) int {
- return exprNewParser().Parse(exprlex)
- }
- func (exprrcvr *exprParserImpl) Parse(exprlex exprLexer) int {
- var exprn int
- var exprVAL exprSymType
- var exprDollar []exprSymType
- _ = exprDollar // silence set and not used
- exprS := exprrcvr.stack[:]
- Nerrs := 0 /* number of errors */
- Errflag := 0 /* error recovery flag */
- exprstate := 0
- exprrcvr.char = -1
- exprtoken := -1 // exprrcvr.char translated into internal numbering
- defer func() {
- // Make sure we report no lookahead when not parsing.
- exprstate = -1
- exprrcvr.char = -1
- exprtoken = -1
- }()
- exprp := -1
- goto exprstack
- ret0:
- return 0
- ret1:
- return 1
- exprstack:
- /* put a state and value onto the stack */
- if exprDebug >= 4 {
- __yyfmt__.Printf("char %v in %v\n", exprTokname(exprtoken), exprStatname(exprstate))
- }
- exprp++
- if exprp >= len(exprS) {
- nyys := make([]exprSymType, len(exprS)*2)
- copy(nyys, exprS)
- exprS = nyys
- }
- exprS[exprp] = exprVAL
- exprS[exprp].yys = exprstate
- exprnewstate:
- exprn = exprPact[exprstate]
- if exprn <= exprFlag {
- goto exprdefault /* simple state */
- }
- if exprrcvr.char < 0 {
- exprrcvr.char, exprtoken = exprlex1(exprlex, &exprrcvr.lval)
- }
- exprn += exprtoken
- if exprn < 0 || exprn >= exprLast {
- goto exprdefault
- }
- exprn = exprAct[exprn]
- if exprChk[exprn] == exprtoken { /* valid shift */
- exprrcvr.char = -1
- exprtoken = -1
- exprVAL = exprrcvr.lval
- exprstate = exprn
- if Errflag > 0 {
- Errflag--
- }
- goto exprstack
- }
- exprdefault:
- /* default state action */
- exprn = exprDef[exprstate]
- if exprn == -2 {
- if exprrcvr.char < 0 {
- exprrcvr.char, exprtoken = exprlex1(exprlex, &exprrcvr.lval)
- }
- /* look through exception table */
- xi := 0
- for {
- if exprExca[xi+0] == -1 && exprExca[xi+1] == exprstate {
- break
- }
- xi += 2
- }
- for xi += 2; ; xi += 2 {
- exprn = exprExca[xi+0]
- if exprn < 0 || exprn == exprtoken {
- break
- }
- }
- exprn = exprExca[xi+1]
- if exprn < 0 {
- goto ret0
- }
- }
- if exprn == 0 {
- /* error ... attempt to resume parsing */
- switch Errflag {
- case 0: /* brand new error */
- exprlex.Error(exprErrorMessage(exprstate, exprtoken))
- Nerrs++
- if exprDebug >= 1 {
- __yyfmt__.Printf("%s", exprStatname(exprstate))
- __yyfmt__.Printf(" saw %s\n", exprTokname(exprtoken))
- }
- fallthrough
- case 1, 2: /* incompletely recovered error ... try again */
- Errflag = 3
- /* find a state where "error" is a legal shift action */
- for exprp >= 0 {
- exprn = exprPact[exprS[exprp].yys] + exprErrCode
- if exprn >= 0 && exprn < exprLast {
- exprstate = exprAct[exprn] /* simulate a shift of "error" */
- if exprChk[exprstate] == exprErrCode {
- goto exprstack
- }
- }
- /* the current p has no shift on "error", pop stack */
- if exprDebug >= 2 {
- __yyfmt__.Printf("error recovery pops state %d\n", exprS[exprp].yys)
- }
- exprp--
- }
- /* there is no state on the stack with an error shift ... abort */
- goto ret1
- case 3: /* no shift yet; clobber input char */
- if exprDebug >= 2 {
- __yyfmt__.Printf("error recovery discards %s\n", exprTokname(exprtoken))
- }
- if exprtoken == exprEofCode {
- goto ret1
- }
- exprrcvr.char = -1
- exprtoken = -1
- goto exprnewstate /* try again in the same state */
- }
- }
- /* reduction by production exprn */
- if exprDebug >= 2 {
- __yyfmt__.Printf("reduce %v in:\n\t%v\n", exprn, exprStatname(exprstate))
- }
- exprnt := exprn
- exprpt := exprp
- _ = exprpt // guard against "declared and not used"
- exprp -= exprR2[exprn]
- // exprp is now the index of $0. Perform the default action. Iff the
- // reduced production is ε, $1 is possibly out of range.
- if exprp+1 >= len(exprS) {
- nyys := make([]exprSymType, len(exprS)*2)
- copy(nyys, exprS)
- exprS = nyys
- }
- exprVAL = exprS[exprp+1]
- /* consult goto table to find next state */
- exprn = exprR1[exprn]
- exprg := exprPgo[exprn]
- exprj := exprg + exprS[exprp].yys + 1
- if exprj >= exprLast {
- exprstate = exprAct[exprg]
- } else {
- exprstate = exprAct[exprj]
- if exprChk[exprstate] != -exprn {
- exprstate = exprAct[exprg]
- }
- }
- // dummy call; replaced with literal code
- switch exprnt {
- case 1:
- exprDollar = exprS[exprpt-1 : exprpt+1]
- //line expr.y:43
- {
- if exprDollar[1].num.IsInt() {
- fmt.Println(exprDollar[1].num.Num().String())
- } else {
- fmt.Println(exprDollar[1].num.String())
- }
- }
- case 3:
- exprDollar = exprS[exprpt-2 : exprpt+1]
- //line expr.y:54
- {
- exprVAL.num = exprDollar[2].num
- }
- case 4:
- exprDollar = exprS[exprpt-2 : exprpt+1]
- //line expr.y:58
- {
- exprVAL.num = exprDollar[2].num.Neg(exprDollar[2].num)
- }
- case 6:
- exprDollar = exprS[exprpt-3 : exprpt+1]
- //line expr.y:65
- {
- exprVAL.num = exprDollar[1].num.Add(exprDollar[1].num, exprDollar[3].num)
- }
- case 7:
- exprDollar = exprS[exprpt-3 : exprpt+1]
- //line expr.y:69
- {
- exprVAL.num = exprDollar[1].num.Sub(exprDollar[1].num, exprDollar[3].num)
- }
- case 9:
- exprDollar = exprS[exprpt-3 : exprpt+1]
- //line expr.y:76
- {
- exprVAL.num = exprDollar[1].num.Mul(exprDollar[1].num, exprDollar[3].num)
- }
- case 10:
- exprDollar = exprS[exprpt-3 : exprpt+1]
- //line expr.y:80
- {
- exprVAL.num = exprDollar[1].num.Quo(exprDollar[1].num, exprDollar[3].num)
- }
- case 12:
- exprDollar = exprS[exprpt-3 : exprpt+1]
- //line expr.y:87
- {
- exprVAL.num = exprDollar[2].num
- }
- }
- goto exprstack /* stack new state and value */
- }
|