github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/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] == 1 && $3 == "%empty") { 39 rulesize[$1] = 0 40 } 41 if(rulesize[$1] == 3 && $3 $4 $5 == "/*empty*/") { 42 rulesize[$1] = 0 43 } 44 } 45 46 # In state dumps, record shift/reduce actions. 47 bison && /^[Ss]tate 0/ { grammar = 0; states = 1 } 48 49 states && /^[Ss]tate / { state = $2 } 50 states { statetext[state] = statetext[state] $0 "\n" } 51 52 states && / shift/ { 53 n = nshift[state]++ 54 if($0 ~ /and go to/) 55 shift[state,n] = $7 # GNU Bison 56 else 57 shift[state,n] = $3 # Plan 9 Yacc 58 shifttoken[state,n] = $1 59 next 60 } 61 states && / (go to|goto)/ { 62 n = nshift[state]++ 63 if($0 ~ /go to/) 64 shift[state,n] = $5 # GNU Bison 65 else 66 shift[state,n] = $3 # Plan 9 Yacc 67 shifttoken[state,n] = $1 68 next 69 } 70 states && / reduce/ { 71 n = nreduce[state]++ 72 if($0 ~ /reduce using rule/) 73 reduce[state,n] = $5 # GNU Bison 74 else 75 reduce[state,n] = $3 # Plan 9 yacc 76 reducetoken[state,n] = $1 77 next 78 } 79 80 # Skip over the summary information printed by Plan 9 yacc. 81 /nonterminals$/,/^maximum spread/ { next } 82 83 # First // comment marks the beginning of the pattern file. 84 /^\/\// { bison = 0; grammar = 0; state = 0 } 85 bison { next } 86 87 # Treat % as first field on line as introducing a pattern (token sequence). 88 # Run it through the LR machine and print the induced "yystate, yychar," 89 # at the point where the error happens. 90 $1 == "%" { 91 nstack = 0 92 state = 0 93 f = 2 94 tok = "" 95 for(;;) { 96 if(tok == "" && f <= NF) { 97 tok = $f 98 f++ 99 } 100 found = 0 101 for(j=0; j<nshift[state]; j++) { 102 if(shifttoken[state,j] == tok) { 103 # print "SHIFT " tok " " state " -> " shift[state,j] 104 stack[nstack++] = state 105 state = shift[state,j] 106 found = 1 107 tok = "" 108 break 109 } 110 } 111 if(found) 112 continue 113 for(j=0; j<nreduce[state]; j++) { 114 t = reducetoken[state,j] 115 if(t == tok || t == "$default" || t == ".") { 116 stack[nstack++] = state 117 rule = reduce[state,j] 118 nstack -= rulesize[rule] 119 state = stack[--nstack] 120 lhs = rulelhs[rule] 121 if(tok != "") 122 --f 123 tok = rulelhs[rule] 124 # print "REDUCE " nstack " " state " " tok " rule " rule " size " rulesize[rule] 125 found = 1 126 break 127 } 128 } 129 if(found) 130 continue 131 132 # No shift or reduce applied - found the error. 133 printf("\t%s, %s,\n", state, tok); 134 break 135 } 136 next 137 } 138 139 # Print other lines verbatim. 140 {print}