github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/core/asm/lexer.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //版权所有2017 Go Ethereum作者
    10  //此文件是Go以太坊库的一部分。
    11  //
    12  //Go-Ethereum库是免费软件:您可以重新分发它和/或修改
    13  //根据GNU发布的较低通用公共许可证的条款
    14  //自由软件基金会,或者许可证的第3版,或者
    15  //(由您选择)任何更高版本。
    16  //
    17  //Go以太坊图书馆的发行目的是希望它会有用,
    18  //但没有任何保证;甚至没有
    19  //适销性或特定用途的适用性。见
    20  //GNU较低的通用公共许可证,了解更多详细信息。
    21  //
    22  //你应该收到一份GNU较低级别的公共许可证副本
    23  //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。
    24  
    25  package asm
    26  
    27  import (
    28  	"fmt"
    29  	"os"
    30  	"strings"
    31  	"unicode"
    32  	"unicode/utf8"
    33  )
    34  
    35  //statefn在
    36  //lexer解析
    37  //当前状态。
    38  type stateFn func(*lexer) stateFn
    39  
    40  //当lexer发现
    41  //一种新的可分割代币。这些都送过去了
    42  //词汇的标记通道
    43  type token struct {
    44  	typ    tokenType
    45  	lineno int
    46  	text   string
    47  }
    48  
    49  //tokentype是lexer的不同类型
    50  //能够解析并返回。
    51  type tokenType int
    52  
    53  const (
    54  eof              tokenType = iota //文件结束
    55  lineStart                         //行开始时发出
    56  lineEnd                           //行结束时发出
    57  invalidStatement                  //任何无效的语句
    58  element                           //元素分析期间的任何元素
    59  label                             //找到标签时发出标签
    60  labelDef                          //找到新标签时发出标签定义
    61  number                            //找到数字时发出数字
    62  stringValue                       //当找到字符串时,将发出StringValue
    63  
    64  Numbers            = "1234567890"                                           //表示任何十进制数的字符
    65  HexadecimalNumbers = Numbers + "aAbBcCdDeEfF"                               //表示任何十六进制的字符
    66  Alpha              = "abcdefghijklmnopqrstuwvxyzABCDEFGHIJKLMNOPQRSTUWVXYZ" //表示字母数字的字符
    67  )
    68  
    69  //字符串实现字符串
    70  func (it tokenType) String() string {
    71  	if int(it) > len(stringtokenTypes) {
    72  		return "invalid"
    73  	}
    74  	return stringtokenTypes[it]
    75  }
    76  
    77  var stringtokenTypes = []string{
    78  	eof:              "EOF",
    79  	invalidStatement: "invalid statement",
    80  	element:          "element",
    81  	lineEnd:          "end of line",
    82  	lineStart:        "new line",
    83  	label:            "label",
    84  	labelDef:         "label definition",
    85  	number:           "number",
    86  	stringValue:      "string",
    87  }
    88  
    89  //lexer是解析的基本构造
    90  //源代码并将其转换为令牌。
    91  //标记由编译器解释。
    92  type lexer struct {
    93  input string //输入包含程序的源代码
    94  
    95  tokens chan token //令牌用于将令牌传递给侦听器
    96  state  stateFn    //
    97  
    98  lineno            int //源文件中的当前行号
    99  start, pos, width int //词法和返回值的位置
   100  
   101  debug bool //
   102  }
   103  
   104  //lex使用给定的源按名称对程序进行lex。它返回一个
   105  //传递令牌的通道。
   106  func Lex(name string, source []byte, debug bool) <-chan token {
   107  	ch := make(chan token)
   108  	l := &lexer{
   109  		input:  string(source),
   110  		tokens: ch,
   111  		state:  lexLine,
   112  		debug:  debug,
   113  	}
   114  	go func() {
   115  		l.emit(lineStart)
   116  		for l.state != nil {
   117  			l.state = l.state(l)
   118  		}
   119  		l.emit(eof)
   120  		close(l.tokens)
   121  	}()
   122  
   123  	return ch
   124  }
   125  
   126  //next返回程序源中的下一个rune。
   127  func (l *lexer) next() (rune rune) {
   128  	if l.pos >= len(l.input) {
   129  		l.width = 0
   130  		return 0
   131  	}
   132  	rune, l.width = utf8.DecodeRuneInString(l.input[l.pos:])
   133  	l.pos += l.width
   134  	return rune
   135  }
   136  
   137  //备份备份最后一个已分析的元素(多字符)
   138  func (l *lexer) backup() {
   139  	l.pos -= l.width
   140  }
   141  
   142  //Peek返回下一个符文,但不前进搜索者
   143  func (l *lexer) peek() rune {
   144  	r := l.next()
   145  	l.backup()
   146  	return r
   147  }
   148  
   149  //忽略推进搜索者并忽略值
   150  func (l *lexer) ignore() {
   151  	l.start = l.pos
   152  }
   153  
   154  //接受检查给定输入是否与下一个rune匹配
   155  func (l *lexer) accept(valid string) bool {
   156  	if strings.ContainsRune(valid, l.next()) {
   157  		return true
   158  	}
   159  
   160  	l.backup()
   161  
   162  	return false
   163  }
   164  
   165  //acceptrun将继续推进seeker直到有效
   166  //再也见不到了。
   167  func (l *lexer) acceptRun(valid string) {
   168  	for strings.ContainsRune(valid, l.next()) {
   169  	}
   170  	l.backup()
   171  }
   172  
   173  //acceptrununtil是acceptrun的倒数,将继续
   174  //把探索者推进直到找到符文。
   175  func (l *lexer) acceptRunUntil(until rune) bool {
   176  //继续运行,直到找到符文
   177  	for i := l.next(); !strings.ContainsRune(string(until), i); i = l.next() {
   178  		if i == 0 {
   179  			return false
   180  		}
   181  	}
   182  
   183  	return true
   184  }
   185  
   186  //blob返回当前值
   187  func (l *lexer) blob() string {
   188  	return l.input[l.start:l.pos]
   189  }
   190  
   191  //向令牌通道发送新令牌以进行处理
   192  func (l *lexer) emit(t tokenType) {
   193  	token := token{t, l.lineno, l.blob()}
   194  
   195  	if l.debug {
   196  		fmt.Fprintf(os.Stderr, "%04d: (%-20v) %s\n", token.lineno, token.typ, token.text)
   197  	}
   198  
   199  	l.tokens <- token
   200  	l.start = l.pos
   201  }
   202  
   203  //lexline是用于词法处理行的状态函数
   204  func lexLine(l *lexer) stateFn {
   205  	for {
   206  		switch r := l.next(); {
   207  		case r == '\n':
   208  			l.emit(lineEnd)
   209  			l.ignore()
   210  			l.lineno++
   211  
   212  			l.emit(lineStart)
   213  		case r == ';' && l.peek() == ';':
   214  			return lexComment
   215  		case isSpace(r):
   216  			l.ignore()
   217  		case isLetter(r) || r == '_':
   218  			return lexElement
   219  		case isNumber(r):
   220  			return lexNumber
   221  		case r == '@':
   222  			l.ignore()
   223  			return lexLabel
   224  		case r == '"':
   225  			return lexInsideString
   226  		default:
   227  			return nil
   228  		}
   229  	}
   230  }
   231  
   232  //lexcomment分析当前位置直到结束
   233  //并丢弃文本。
   234  func lexComment(l *lexer) stateFn {
   235  	l.acceptRunUntil('\n')
   236  	l.ignore()
   237  
   238  	return lexLine
   239  }
   240  
   241  //lexmlabel解析当前标签,发出并返回
   242  //lex文本状态函数用于推进分析
   243  //过程。
   244  func lexLabel(l *lexer) stateFn {
   245  	l.acceptRun(Alpha + "_")
   246  
   247  	l.emit(label)
   248  
   249  	return lexLine
   250  }
   251  
   252  //lexinsideString对字符串内部进行lexi,直到
   253  //
   254  //它返回lex文本状态函数。
   255  func lexInsideString(l *lexer) stateFn {
   256  	if l.acceptRunUntil('"') {
   257  		l.emit(stringValue)
   258  	}
   259  
   260  	return lexLine
   261  }
   262  
   263  func lexNumber(l *lexer) stateFn {
   264  	acceptance := Numbers
   265  	if l.accept("0") || l.accept("xX") {
   266  		acceptance = HexadecimalNumbers
   267  	}
   268  	l.acceptRun(acceptance)
   269  
   270  	l.emit(number)
   271  
   272  	return lexLine
   273  }
   274  
   275  func lexElement(l *lexer) stateFn {
   276  	l.acceptRun(Alpha + "_" + Numbers)
   277  
   278  	if l.peek() == ':' {
   279  		l.emit(labelDef)
   280  
   281  		l.accept(":")
   282  		l.ignore()
   283  	} else {
   284  		l.emit(element)
   285  	}
   286  	return lexLine
   287  }
   288  
   289  func isLetter(t rune) bool {
   290  	return unicode.IsLetter(t)
   291  }
   292  
   293  func isSpace(t rune) bool {
   294  	return unicode.IsSpace(t)
   295  }
   296  
   297  func isNumber(t rune) bool {
   298  	return unicode.IsNumber(t)
   299  }