gpt4 book ai didi

go - go tool yacc 中最简单的解析器

转载 作者:IT王子 更新时间:2023-10-29 01:09:02 26 4
gpt4 key购买 nike

使用这个命令:

go tool yacc -p Verb -o verb.go boilerplate.y

尝试构建这个 yacc 文件:

// boilerplate.y
%{

package main

import (
"bufio"
"fmt"
"os"
"unicode"
)

%}

%%

.|\n ECHO;

%%

func main() {
fi := bufio.NewReader(os.NewFile(0, "stdin"))
s, err := fi.ReadString('\n')
if err != nil {
fmt.Println('error', err)
}

VerbParse(&VerbLex{s: s})
}

错误:第一条规则语法错误:boilerplate.y:16

成功地让这个例子工作:

https://github.com/golang-samples/yacc/blob/master/simple/calc.y

尝试构建我自己的并完成 lex & yacc 书。资源似乎有限到不存在。

最佳答案

您的规范中有一个不正确的规则

规范文件具有以下声明:

declarations
%%
rules
%%
programs

规则定义为:

A  :  BODY  ;

其中A是一个非终结符,而BODY则由tokens(终结符)、非终结符和文字组成。 :; 是规则声明语法的必需组件。

因此规则:

.|\n   ECHO;

语法不正确。

由于您只是尝试回显输入,因此下面是一个基于 calc.y 的非常简单的实现(文件 echo.y):

规则

%%

in : /* empty */
| in input '\n'
{ fmt.Printf("Read character: %s\n", $2) }
;

input : CHARACTER
| input CHARACTER
{ $$ = $1 + $2 }
;

程序

%%

type InputLex struct {
// contains one complete input string (with the trailing \n)
s string
// used to keep track of parser position along the above imput string
pos int
}

func (l *InputLex) Lex(lval *InputSymType) int {
var c rune = ' '

// skip through all the spaces, both at the ends and in between
for c == ' ' {
if l.pos == len(l.s) {
return 0
}
c = rune(l.s[l.pos])
l.pos += 1
}

// only look for input characters that are either digits or lower case
// to do more specific parsing, you'll define more tokens and have a
// more complex parsing logic here, choosing which token to return
// based on parsed input
if unicode.IsDigit(c) || unicode.IsLower(c) {
lval.val = string(c)
return CHARACTER
}

// do not return any token in case of unrecognized grammer
// this results in syntax error
return int(c)
}

func (l *InputLex) Error(s string) {
fmt.Printf("syntax error: %s\n", s)
}

func main() {
// same as in calc.y
}

func readline(fi *bufio.Reader) (string, bool) {
// same as in calc.y
}

要编译和运行该程序,请在命令提示符处执行以下操作:

go tool yacc -o echo.go -p Input echo.y
go run echo.go

如您所见,您必须在 Lex 方法中定义自己的解析规则。结构 InputLex 旨在在解析输入时保存值。 InputSymType 是自动生成的,由规范的 declaration 部分中声明的 %union 定义。

据我所知,没有办法直接使用 JISON 或正则表达式来使用 go 的 yacc 工具进行匹配。您可能需要查看其他一些库。

可在此处找到更多详细信息:http://dinosaur.compilertools.net/yacc/

完整的工作代码在这里:https://play.golang.org/p/u1QxwRKLCl

关于go - go tool yacc 中最简单的解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38645476/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com