github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/gc/bisonerrors (about) 1 #!/usr/bin/awk -f 2 # Copyright 2010 The Go Authors. All rights reserved. 3 # Use of this source code is governed by a BSD-style 4 # license that can be found in the LICENSE file. 5 6 # This program implements the core idea from 7 # 8 # Clinton L. Jeffery, Generating LR syntax error messages from examples, 9 # ACM TOPLAS 25(5) (September 2003). http://doi.acm.org/10.1145/937563.937566 10 # 11 # It reads Bison's summary of a grammar followed by a file 12 # like go.errors, replacing lines beginning with % by the 13 # yystate and yychar that will be active when an error happens 14 # while parsing that line. 15 # 16 # Unlike the system described in the paper, the lines in go.errors 17 # give grammar symbol name lists, not actual program fragments. 18 # This is a little less programmer-friendly but doesn't require being 19 # able to run the text through lex.c. 20 21 BEGIN{ 22 bison = 1 23 grammar = 0 24 states = 0 25 } 26 27 # In Grammar section of y.output, 28 # record lhs and length of rhs for each rule. 29 bison && /^Grammar/ { grammar = 1 } 30 bison && /^(Terminals|state 0)/ { grammar = 0 } 31 grammar && NF>0 { 32 if($2 != "|") { 33 r = $2 34 sub(/:$/, "", r) 35 } 36 rulelhs[$1] = r 37 rulesize[$1] = NF-2 38 if(rulesize[$1] == 3 && $3 $4 $5 == "/*empty*/") { 39 rulesize[$1] = 0 40 } 41 } 42 43 # In state dumps, record shift/reduce actions. 44 bison && /^[Ss]tate 0/ { grammar = 0; states = 1 } 45 46 states && /^[Ss]tate / { state = $2 } 47 states { statetext[state] = statetext[state] $0 "\n" } 48 49 states && / shift/ { 50 n = nshift[state]++ 51 if($0 ~ /and go to/) 52 shift[state,n] = $7 # GNU Bison 53 else 54 shift[state,n] = $3 # Plan 9 Yacc 55 shifttoken[state,n] = $1 56 next 57 } 58 states && / (go to|goto)/ { 59 n = nshift[state]++ 60 if($0 ~ /go to/) 61 shift[state,n] = $5 # GNU Bison 62 else 63 shift[state,n] = $3 # Plan 9 Yacc 64 shifttoken[state,n] = $1 65 next 66 } 67 states && / reduce/ { 68 n = nreduce[state]++ 69 if($0 ~ /reduce using rule/) 70 reduce[state,n] = $5 # GNU Bison 71 else 72 reduce[state,n] = $3 # Plan 9 yacc 73 reducetoken[state,n] = $1 74 next 75 } 76 77 # Skip over the summary information printed by Plan 9 yacc. 78 /nonterminals$/,/^maximum spread/ { next } 79 80 # First // comment marks the beginning of the pattern file. 81 /^\/\// { bison = 0; grammar = 0; state = 0 } 82 bison { next } 83 84 # Treat % as first field on line as introducing a pattern (token sequence). 85 # Run it through the LR machine and print the induced "yystate, yychar," 86 # at the point where the error happens. 87 $1 == "%" { 88 nstack = 0 89 state = 0 90 f = 2 91 tok = "" 92 for(;;) { 93 if(tok == "" && f <= NF) { 94 tok = $f 95 f++ 96 } 97 found = 0 98 for(j=0; j<nshift[state]; j++) { 99 if(shifttoken[state,j] == tok) { 100 # print "SHIFT " tok " " state " -> " shift[state,j] 101 stack[nstack++] = state 102 state = shift[state,j] 103 found = 1 104 tok = "" 105 break 106 } 107 } 108 if(found) 109 continue 110 for(j=0; j<nreduce[state]; j++) { 111 t = reducetoken[state,j] 112 if(t == tok || t == "$default" || t == ".") { 113 stack[nstack++] = state 114 rule = reduce[state,j] 115 nstack -= rulesize[rule] 116 state = stack[--nstack] 117 lhs = rulelhs[rule] 118 if(tok != "") 119 --f 120 tok = rulelhs[rule] 121 # print "REDUCE " nstack " " state " " tok " rule " rule " size " rulesize[rule] 122 found = 1 123 break 124 } 125 } 126 if(found) 127 continue 128 129 # No shift or reduce applied - found the error. 130 printf("\t%s, %s,\n", state, tok); 131 break 132 } 133 next 134 } 135 136 # Print other lines verbatim. 137 {print}