[英]Simplest of parsers in go tool yacc
使用這個命令:
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})
}
錯誤: bad syntax on first rule: boilerplate.y:16
錯誤: bad syntax on first rule: boilerplate.y:16
成功地讓這個例子工作:
https://github.com/golang-samples/yacc/blob/master/simple/calc.y
嘗試構建我自己的並通過 lex & yacc 書工作。 資源似乎僅限於不存在。
您的規格中有不正確的rule
。
規范文件具有以下聲明:
declarations
%%
rules
%%
programs
rule
定義為:
A : BODY ;
其中A是非終端符號,而BODY由令牌(終端符號),非終端和文字組成。 :
和;
是規則聲明語法的必需組件。
因此規則:
.|\n ECHO;
在語法上是不正確的。
由於您只是嘗試回顯輸入, calc.y
將基於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
方法中定義自己的解析規則。 struct InputLex
用於在解析輸入時保存值。 InputSymType
是自動生成的,由規范的declaration
部分中declaration
的%union
定義。
據我所知,沒有辦法直接使用JISON或正則表達式使用go的yacc
工具進行匹配。 您可能需要查看其他一些庫。
更多細節可以在這里找到: http : //dinosaur.compilertools.net/yacc/
完整的工作代碼: https : //play.golang.org/p/u1QxwRKLCl
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.