Advertisement
Guest User

Untitled

a guest
Jul 21st, 2019
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.51 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4. "flag"
  5. "fmt"
  6. "io"
  7. "os"
  8. "os/exec"
  9. "sort"
  10. "strings"
  11. "time"
  12. )
  13.  
  14. func init() {
  15. sort.Strings(builtins)
  16. }
  17.  
  18. func main() {
  19. lex := flag.Bool("lex", false, "lex")
  20. flag.Parse()
  21. data := []string{
  22. "xxh -k 64 scripts/basic.go scripts/quote.go",
  23. "find tmp/ -type f -name *txt",
  24. "find /tmp -type f ; xxh -k 64 scripts/quote.go",
  25. "find /tmp -type f || xxh -k 64 /tmp",
  26. "find /tmp -type f && xxh -k 64 /tmp",
  27. "echo foobar; find /tmp -type f && xxh -k 64 /tmp",
  28. "echo foobar#a comment",
  29. "find tmp/ -maxdepth 1 -type f | xxh",
  30. "NAME=foobar",
  31. "NAME=foobar;",
  32. "NAME=",
  33. "NAME=;",
  34. "NAME=foo bar baz",
  35. "$VAR",
  36. "${VAR}",
  37. "$((1+35+1))",
  38. "$((1 + (7*5) + 1))",
  39. "$((1 + (7 * VAR) + 1))",
  40. "$((1 + (7 * $VAR) + 1))",
  41. }
  42. if *lex {
  43. lexOnly(data)
  44. } else {
  45. parseOnly(data)
  46. }
  47. }
  48.  
  49. func parseOnly(data []string) {
  50. for i, d := range data {
  51. if i > 0 {
  52. fmt.Println("---")
  53. }
  54. fmt.Println("parsing:", d)
  55. if c, err := NewParser(d).Parse(); err != nil {
  56. fmt.Fprintln(os.Stderr, err)
  57. } else {
  58. fmt.Println(c.String())
  59. }
  60. }
  61. }
  62.  
  63. func lexOnly(data []string) {
  64. for i, d := range data {
  65. if i > 0 {
  66. fmt.Println("---")
  67. }
  68. fmt.Println("lexing:", d)
  69. x := Lex(d)
  70. for t := x.Next(); t.Type != EOF; t = x.Next() {
  71. fmt.Println(">", t)
  72. }
  73. }
  74. }
  75.  
  76. type shell struct {
  77. globals map[string]string
  78. locals map[string]string
  79.  
  80. level uint64
  81. pwd string // previous working directory
  82. cwd string // current working directory
  83. home string // home directory
  84. now time.Time
  85. }
  86.  
  87. func NewShell() *shell {
  88. x := shell{
  89. globals: make(map[string]string),
  90. locals: make(map[string]string),
  91. now: time.Now(),
  92. cwd: os.TempDir(),
  93. pwd: os.TempDir(),
  94. home: os.TempDir(),
  95. }
  96. x.level++
  97. return &x
  98. }
  99.  
  100. func (s *shell) Exec() error {
  101. return s.execCommand(nil)
  102. }
  103.  
  104. func (s *shell) execCommand(e Exec) error {
  105. var err error
  106. switch e.(type) {
  107. case sequence:
  108. case pipeline:
  109. case logical:
  110. case command:
  111. default:
  112. err = fmt.Errorf("unsupported syntax %T", e)
  113. }
  114. return err
  115. }
  116.  
  117. func (s *shell) Subshell() *shell {
  118. x := NewShell()
  119. x.level = s.level + 1
  120. for k, v := range s.globals {
  121. x.globals[k] = v
  122. }
  123. for k, v := range s.locals {
  124. x.locals[k] = v
  125. }
  126. return x
  127. }
  128.  
  129. const (
  130. bindLowest = iota
  131. bindEqual
  132. bindShift
  133. bindPlus
  134. bindMultiply
  135. bindExponent
  136. bindNegation
  137. bindUnary
  138. bindLogical
  139. bindPipe
  140. )
  141.  
  142. var powers = map[int]int{
  143. Background: bindLowest,
  144. Sequence: bindLowest,
  145. And: bindLogical,
  146. Or: bindLogical,
  147. Pipeline: bindPipe,
  148. }
  149.  
  150. type Exec interface {
  151. Exec() error
  152. Wait() error
  153. fmt.Stringer
  154. }
  155.  
  156. type literal string
  157.  
  158. func (i literal) String() string {
  159. return string(i)
  160. }
  161.  
  162. func (i literal) Exec() error { return nil }
  163. func (i literal) Wait() error { return nil }
  164.  
  165. type command struct {
  166. cmd *exec.Cmd
  167. async bool
  168.  
  169. stdout string
  170. stderr string
  171. stdin string
  172. }
  173.  
  174. func newCommand(as []string) *command {
  175. var c command
  176. c.cmd = exec.Command(as[0], as[1:]...)
  177.  
  178. return &c
  179. }
  180.  
  181. func (c command) String() string {
  182. var b strings.Builder
  183. b.WriteString(c.cmd.Args[0])
  184. if len(c.cmd.Args) > 1 {
  185. for _, a := range c.cmd.Args[1:] {
  186. b.WriteRune(space)
  187. b.WriteString(a)
  188. }
  189. }
  190. return b.String()
  191. }
  192.  
  193. func (c command) Exec() error {
  194. if c.cmd.Stdout == nil {
  195. c.cmd.Stdout = os.Stdout
  196. }
  197. if c.cmd.Stderr == nil {
  198. c.cmd.Stderr = os.Stderr
  199. }
  200. return c.cmd.Start()
  201. }
  202.  
  203. func (c command) Wait() error {
  204. err := c.Exec()
  205. if err == nil {
  206. err = c.cmd.Wait()
  207. }
  208. return err
  209. }
  210.  
  211. type sequence []Exec
  212.  
  213. func (es sequence) String() string {
  214. var b strings.Builder
  215. for i, e := range es {
  216. if i >= 1 {
  217. b.WriteRune(space)
  218. }
  219. b.WriteString(e.String())
  220. b.WriteRune(semicolon)
  221. }
  222. return b.String()
  223. }
  224.  
  225. func (es sequence) Exec() error {
  226. return es.Wait()
  227. }
  228.  
  229. func (es sequence) Wait() error {
  230. var err error
  231. for _, e := range es {
  232. err = e.Wait()
  233. }
  234. return err
  235. }
  236.  
  237. type logical struct {
  238. op int
  239. left Exec
  240. right Exec
  241. }
  242.  
  243. func (i logical) String() string {
  244. var op string
  245. switch i.op {
  246. case And:
  247. op = "&&"
  248. case Or:
  249. op = "||"
  250. default:
  251. op = "???"
  252. }
  253. var b strings.Builder
  254. b.WriteString(i.left.String())
  255. b.WriteRune(space)
  256. b.WriteString(op)
  257. b.WriteRune(space)
  258. b.WriteString(i.right.String())
  259.  
  260. return b.String()
  261. }
  262.  
  263. func (i logical) Exec() error {
  264. return i.Wait()
  265. }
  266.  
  267. func (i logical) Wait() error {
  268. var fn func(Exec, Exec) error
  269. switch i.op {
  270. case Or:
  271. fn = evalOr
  272. case And:
  273. fn = evalAnd
  274. default:
  275. }
  276. if fn == nil {
  277. return fmt.Errorf("unkown logical operator")
  278. }
  279. return fn(i.left, i.right)
  280. }
  281.  
  282. func evalOr(left, right Exec) error {
  283. err := left.Wait()
  284. if err != nil {
  285. err = right.Wait()
  286. }
  287. return err
  288. }
  289.  
  290. func evalAnd(left, right Exec) error {
  291. err := left.Wait()
  292. if err == nil {
  293. err = right.Wait()
  294. }
  295. return err
  296. }
  297.  
  298. type pipeline []Exec
  299.  
  300. func (p pipeline) Exec() error {
  301. return p.Wait()
  302. }
  303.  
  304. func (p pipeline) Wait() error {
  305. var pipe io.Reader = os.Stdin
  306. for i, e := range p {
  307. if c, ok := e.(*command); ok {
  308. c.cmd.Stdin = pipe
  309. pipe, _ = c.cmd.StdoutPipe()
  310. } else {
  311. return fmt.Errorf("invalid construct")
  312. }
  313.  
  314. if i < len(p)-1 {
  315. go e.Wait()
  316. }
  317. }
  318. go io.Copy(os.Stdout, pipe)
  319. return p[len(p)-1].Wait()
  320. }
  321.  
  322. func (p pipeline) String() string {
  323. var b strings.Builder
  324. for i, e := range p {
  325. if i >= 1 {
  326. b.WriteRune(space)
  327. b.WriteRune(pipe)
  328. b.WriteRune(space)
  329. }
  330. b.WriteString(e.String())
  331. }
  332. return b.String()
  333. }
  334.  
  335. type assignment struct {
  336. ident string
  337. value Exec
  338. }
  339.  
  340. func (a assignment) Exec() error {
  341. return nil
  342. }
  343.  
  344. func (a assignment) Wait() error {
  345. return nil
  346. }
  347.  
  348. func (a assignment) String() string {
  349. var b strings.Builder
  350.  
  351. b.WriteString(a.ident)
  352. b.WriteRune(equal)
  353. if a.value != nil {
  354. b.WriteString(a.value.String())
  355. }
  356.  
  357. return b.String()
  358. }
  359.  
  360. type arithmetic struct {
  361. expr Expression
  362. }
  363.  
  364. func (a arithmetic) String() string {
  365. return a.expr.String()
  366. }
  367.  
  368. func (a arithmetic) Exec() error {
  369. return nil
  370. }
  371.  
  372. func (a arithmetic) Wait() error {
  373. return nil
  374. }
  375.  
  376. type Expression interface {
  377. fmt.Stringer
  378. }
  379.  
  380. type unary struct {
  381. op byte
  382. right Expression
  383. }
  384.  
  385. type infix struct {
  386. op byte
  387. left Expression
  388. right Expression
  389. }
  390.  
  391. var builtins = []string{
  392. "echo",
  393. "cd",
  394. "pwd",
  395. "now",
  396. "export",
  397. "true",
  398. "false",
  399. "wait",
  400. }
  401.  
  402. type parser struct {
  403. lex *lexer
  404.  
  405. // prefix infix function to parse shell construct
  406. prefix map[int]func() (Exec, error)
  407. infix map[int]func(Exec) (Exec, error)
  408.  
  409. curr Token
  410. peek Token
  411. }
  412.  
  413. type mathparser struct {
  414. lex *lexer
  415.  
  416. prefix map[byte]func() (Expression, error)
  417. infix map[byte]func(Expression) (Expression, error)
  418.  
  419. curr Token
  420. peek Token
  421. }
  422.  
  423. func parseMath(lex *lexer) (Expression, error) {
  424. var p mathparser
  425. p.init(lex)
  426.  
  427. return p.parseExpression(bindLowest)
  428. }
  429.  
  430. func (p *mathparser) init(lex *lexer) {
  431. p.lex = lex
  432. p.prefix = map[byte]func() (Expression, error){}
  433. p.infix = map[byte]func(Expression) (Expression, error){}
  434.  
  435. p.nextToken()
  436. p.nextToken()
  437. }
  438.  
  439. func (p *mathparser) parseExpression(power int) (Expression, error) {
  440. prefix, ok := p.prefix[p.curr.Type]
  441. if !ok {
  442. return nil, fmt.Errorf("can not parse %s as prefix operator", p.curr)
  443. }
  444. left, err := prefix()
  445. if err != nil {
  446. return nil, err
  447. }
  448. for power < p.peekPower() {
  449. infix, ok := p.infix[p.peek.Type]
  450. if !ok {
  451. return nil, fmt.Errorf("can not parse %s as infix operator", p.curr)
  452. }
  453. left, err = infix(left)
  454. if err != nil {
  455. return nil, err
  456. }
  457. }
  458. return left, nil
  459. }
  460.  
  461. func (m *mathparser) nextToken() {
  462. m.curr = m.peek
  463. m.peek = m.lext.nextToken()
  464. }
  465.  
  466. func NewParser(str string) *parser {
  467. var p parser
  468. p.prefix = map[int]func() (Exec, error){
  469. Literal: p.parseSimple,
  470. Builtin: p.parseSimple,
  471. Identifier: p.parseAssignment,
  472. Arithmetic: p.parseArithmetic,
  473. }
  474. p.infix = map[int]func(Exec) (Exec, error){
  475. And: p.parseLogical,
  476. Or: p.parseLogical,
  477. Pipeline: p.parsePipe,
  478. }
  479. p.lex = Lex(str)
  480. p.nextToken()
  481. p.nextToken()
  482.  
  483. return &p
  484. }
  485.  
  486. func (p *parser) Parse() (Exec, error) {
  487. xs := make(sequence, 0, 8)
  488. for !p.isDone() {
  489. e, err := p.parseCommand(bindLowest)
  490. if err != nil {
  491. return nil, err
  492. }
  493. xs = append(xs, e)
  494. p.nextToken()
  495. }
  496. return xs, nil
  497. }
  498.  
  499. func (p *parser) parseCommand(power int) (Exec, error) {
  500. fmt.Println("parseCommand:", p.curr)
  501. prefix, ok := p.prefix[p.curr.Type]
  502. if !ok {
  503. return nil, fmt.Errorf("can not parse %s as command prefix", p.curr)
  504. }
  505. e, err := prefix()
  506. if err != nil {
  507. return nil, err
  508. }
  509. for !p.isComplete() && power < p.currPower() {
  510. infix, ok := p.infix[p.curr.Type]
  511. if !ok {
  512. return nil, fmt.Errorf("can not parse %s as command infix", p.peek)
  513. }
  514. e, err = infix(e)
  515. if err != nil {
  516. return nil, err
  517. }
  518. }
  519. return e, nil
  520. }
  521.  
  522. func (p *parser) parseArithmetic() (Exec, error) {
  523. fmt.Println("parseArithmetic:", p.curr)
  524. i := literal(p.curr.Literal)
  525. if _, err := parseMath(p.lex); err != nil {
  526. return nil, err
  527. }
  528. p.nextToken()
  529. return i, nil
  530. }
  531.  
  532. func (p *parser) parseAssignment() (Exec, error) {
  533. fmt.Println("parseAssignment:", p.curr)
  534. a := assignment{ident: p.curr.Literal}
  535. p.nextToken()
  536. if p.curr.Type != Assign {
  537. return nil, fmt.Errorf("invalid syntax: %s", p.curr)
  538. }
  539. var err error
  540. if typ := p.peek.Type; typ != EOF && typ != Sequence {
  541. p.nextToken()
  542. a.value, err = p.parseSimple()
  543. } else {
  544. p.nextToken()
  545. }
  546. return a, err
  547. }
  548.  
  549. func (p *parser) parsePipe(left Exec) (Exec, error) {
  550. fmt.Println("parsePipe:", p.curr)
  551. ps := make(pipeline, 0, 8)
  552. ps = append(ps, left)
  553.  
  554. for !p.isComplete() {
  555. p.nextToken()
  556. left, err := p.parseSimple()
  557. if err != nil {
  558. return nil, err
  559. }
  560. ps = append(ps, left)
  561. if p.curr.Type != Pipeline && p.curr.Type != EOF {
  562. return nil, fmt.Errorf("invalid syntax: %s", p.peek)
  563. }
  564. }
  565. return ps, nil
  566. }
  567.  
  568. func (p *parser) parseLogical(left Exec) (Exec, error) {
  569. fmt.Println("parseLogical:", p.curr)
  570. logic := logical{
  571. left: left,
  572. op: p.curr.Type,
  573. }
  574. p.nextToken()
  575. right, err := p.parseSimple()
  576. if err != nil {
  577. return nil, err
  578. }
  579. logic.right = right
  580. return logic, nil
  581. }
  582.  
  583. func (p *parser) parseSimple() (Exec, error) {
  584. fmt.Println("parseSimple:", p.curr)
  585. var args []string
  586. for {
  587. if p.isComplete() || p.isControl(p.curr) {
  588. break
  589. }
  590. args = append(args, p.curr.Literal)
  591. p.nextToken()
  592. }
  593. return newCommand(args), nil
  594. }
  595.  
  596. func (p *parser) isControl(tok Token) bool {
  597. t := tok.Type
  598. return t == And || t == Or || t == Background || t == Pipeline || t == Sequence || t == EOF
  599. }
  600.  
  601. func (p *parser) isComplete() bool {
  602. return p.curr.Type == EOF || p.curr.Type == Sequence || p.curr.Type == Comment
  603. }
  604.  
  605. func (p *parser) isDone() bool {
  606. return p.curr.Type == EOF
  607. }
  608.  
  609. func (p *parser) currPower() int {
  610. return bindingPower(p.curr)
  611. }
  612.  
  613. func (p *parser) peekPower() int {
  614. return bindingPower(p.peek)
  615. }
  616.  
  617. func (p *parser) nextToken() {
  618. if p.isDone() {
  619. return
  620. }
  621. p.curr = p.peek
  622. p.peek = p.lex.Next()
  623. if p.curr.Type == Comment {
  624. for !p.isDone() {
  625. p.nextToken()
  626. }
  627. }
  628. }
  629.  
  630. func bindingPower(tok Token) int {
  631. p, ok := powers[tok.Type]
  632. if !ok {
  633. p = bindLowest
  634. }
  635. return p
  636. }
  637.  
  638. const (
  639. eof = 0
  640. tab = '\t'
  641. space = ' '
  642. dollar = '$'
  643. semicolon = ';'
  644. ampersand = '&'
  645. pipe = '|'
  646. comment = '#'
  647. quote = '\''
  648. lparen = '('
  649. rparen = ')'
  650. lcurly = '{'
  651. rcurly = '}'
  652. langle = '<'
  653. rangle = '>'
  654. equal = '='
  655. question = '?'
  656. bang = '!'
  657. plus = '+'
  658. minus = '-'
  659. star = '*'
  660. slash = '/'
  661. )
  662.  
  663. const (
  664. EOF = -(iota + 1)
  665. Literal
  666. Builtin
  667. Identifier
  668. Variable
  669. Arithmetic
  670. Comment
  671. And
  672. Or
  673. Pipeline
  674. Background
  675. Sequence
  676. Assign
  677. Unknown
  678. Invalid
  679. )
  680.  
  681. var labels = []string{
  682. "invalid",
  683. "unknown",
  684. "assignment",
  685. "sequence",
  686. "background",
  687. "pipeline",
  688. "or",
  689. "and",
  690. "comment",
  691. "arithmetic",
  692. "variable",
  693. "identifier",
  694. "builtin",
  695. "literal",
  696. "eof",
  697. }
  698.  
  699. type Token struct {
  700. Op byte
  701. Type int
  702. Literal string
  703. }
  704.  
  705. func (t Token) String() string {
  706. n := len(labels) + t.Type
  707.  
  708. var str string
  709. if n < 0 {
  710. str = labels[0]
  711. } else {
  712. str = labels[n]
  713. }
  714. return fmt.Sprintf("<%s (%s)>", str, t.Literal)
  715. }
  716.  
  717. type lexerState uint16
  718.  
  719. const (
  720. lexDefault lexerState = iota
  721. lexStrict
  722. lexWeak
  723. lexSubshell
  724. lexArithmetic
  725. )
  726.  
  727. type lexer struct {
  728. input []byte
  729.  
  730. char byte
  731. pos int
  732. next int
  733.  
  734. scan func() Token
  735. }
  736.  
  737. func Lex(str string) *lexer {
  738. x := lexer{input: []byte(str)}
  739. x.readByte()
  740.  
  741. return &x
  742. }
  743.  
  744. func (x *lexer) scanArithmetic() Token {
  745. var tok Token
  746. if b := x.peekByte(); x.char == rparen && (b == rparen || b == eof) {
  747. fmt.Println("all done")
  748. x.scan = nil
  749.  
  750. tok.Type = EOF
  751. return tok
  752. }
  753. switch {
  754. case isDigit(x.char):
  755. x.readNumber(&tok)
  756. case isLetter(x.char) || x.char == dollar:
  757. if x.char == dollar {
  758. x.readByte()
  759. }
  760. tok.Type = Variable
  761. x.readLiteral(&tok)
  762. default:
  763. tok.Literal = string(x.char)
  764. tok.Type, tok.Op = Arithmetic, x.char
  765. x.readByte()
  766. }
  767. return tok
  768. }
  769.  
  770. func (x *lexer) Next() Token {
  771. var tok Token
  772. if x.char == eof {
  773. tok.Type = EOF
  774. return tok
  775. }
  776.  
  777. x.skipBlank()
  778. if x.scan != nil {
  779. return x.scan()
  780. }
  781.  
  782. switch {
  783. case x.char == '$':
  784. x.readByte()
  785. if b := x.peekByte(); x.char == lcurly || isLetter(b) {
  786. tok.Type = Variable
  787. if x.char == lcurly {
  788. x.readByte()
  789. x.readUntil(&tok, func(b byte) bool { return b == rcurly })
  790. } else {
  791. x.readLiteral(&tok)
  792. }
  793. } else if x.char == lparen && b == lparen {
  794. tok.Type = Arithmetic
  795. x.readByte()
  796. x.scan = x.scanArithmetic
  797. } else if x.char == question || x.char == bang {
  798. tok.Type = Variable
  799. }
  800. case isControl(x.char):
  801. x.readControl(&tok)
  802. case isComment(x.char):
  803. x.readByte()
  804. x.readComment(&tok)
  805. default:
  806. x.readLiteral(&tok)
  807. if b := x.peekByte(); x.char == equal && (!isBlank(b) || b == eof) {
  808. tok.Type = Identifier
  809. }
  810. }
  811. x.readByte()
  812.  
  813. return tok
  814. }
  815.  
  816. func (x *lexer) readUntil(tok *Token, fn func(b byte) bool) {
  817. pos := x.pos
  818. for !fn(x.char) {
  819. x.readByte()
  820. }
  821. tok.Literal = string(x.input[pos:x.pos])
  822. }
  823.  
  824. func (x *lexer) readNumber(tok *Token) {
  825. pos := x.pos
  826. for isDigit(x.char) {
  827. x.readByte()
  828. }
  829. tok.Literal = string(x.input[pos:x.pos])
  830. tok.Type = Literal
  831. }
  832.  
  833. func (x *lexer) readLiteral(tok *Token) {
  834. pos := x.pos
  835. for {
  836. if isSeparator(x.char) || isComment(x.char) {
  837. break
  838. }
  839. x.readByte()
  840. }
  841.  
  842. tok.Literal = string(x.input[pos:x.pos])
  843. if tok.Type >= 0 {
  844. tok.Type = Literal
  845. }
  846. if isSeparator(x.char) || isComment(x.char) {
  847. x.unreadByte()
  848. }
  849. ix := sort.SearchStrings(builtins, tok.Literal)
  850. if ix < len(builtins) && builtins[ix] == tok.Literal {
  851. tok.Type = Builtin
  852. }
  853. }
  854.  
  855. func (x *lexer) readComment(tok *Token) {
  856. pos := x.pos
  857. for x.char != eof {
  858. x.readByte()
  859. }
  860. tok.Literal, tok.Type = string(x.input[pos:x.pos]), Comment
  861. }
  862.  
  863. func (x *lexer) readControl(tok *Token) {
  864. switch x.char {
  865. case ampersand:
  866. x.readByte()
  867. if x.char == ampersand {
  868. tok.Type = And
  869. } else {
  870. tok.Type = Background
  871. }
  872. case pipe:
  873. x.readByte()
  874. if x.char == pipe {
  875. tok.Type = Or
  876. } else {
  877. tok.Type = Pipeline
  878. }
  879. case semicolon:
  880. tok.Type = Sequence
  881. case equal:
  882. tok.Type = Assign
  883. default:
  884. tok.Type = Invalid
  885. }
  886. }
  887.  
  888. func (x *lexer) peekByte() byte {
  889. if x.next >= len(x.input) {
  890. return eof
  891. }
  892. return x.input[x.next]
  893. }
  894.  
  895. func (x *lexer) readByte() {
  896. if x.next >= len(x.input) {
  897. x.char = eof
  898. } else {
  899. x.char = x.input[x.next]
  900. }
  901. x.pos = x.next
  902. x.next++
  903. }
  904.  
  905. func (x *lexer) unreadByte() {
  906. x.next = x.pos
  907. x.pos--
  908. }
  909.  
  910. func (x *lexer) skipBlank() {
  911. for isBlank(x.char) {
  912. x.readByte()
  913. }
  914. }
  915.  
  916. func isSeparator(b byte) bool {
  917. return isBlank(b) || isControl(b)
  918. }
  919.  
  920. func isBlank(b byte) bool {
  921. return b == space || b == tab || b == eof
  922. }
  923.  
  924. func isMath(b byte) bool {
  925. return b == plus || b == minus || b == slash || b == star
  926. }
  927.  
  928. func isControl(b byte) bool {
  929. return b == ampersand || b == pipe || b == semicolon || b == equal
  930. }
  931.  
  932. func isComment(b byte) bool {
  933. return b == comment
  934. }
  935.  
  936. func isQuote(b byte) bool {
  937. return b == quote
  938. }
  939.  
  940. func isLetter(b byte) bool {
  941. return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z')
  942. }
  943.  
  944. func isDigit(b byte) bool {
  945. return b >= '0' && b <= '9'
  946. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement