fixes #10665 (#13141) [backport]

(cherry picked from commit fadbd8f70d)
This commit is contained in:
Andreas Rumpf
2020-01-14 13:51:28 +01:00
committed by narimiran
parent 74350447ed
commit a3d5a3ca9b
4 changed files with 101 additions and 45 deletions

47
tools/grammar_nanny.nim Normal file
View File

@@ -0,0 +1,47 @@
## Simple tool to check for obvious mistakes in Nim's
## grammar.txt file.
import std / [strutils, sets]
import ".." / compiler / [
llstream, ast, lexer, options, msgs, idents,
lineinfos, pathutils]
proc checkGrammarFileImpl(cache: IdentCache, config: ConfigRef) =
var f = AbsoluteFile"doc/grammar.txt"
let data = readFile(f.string).multiReplace({"IND{=}": "SAME_IND", "'": "\""})
var stream = llStreamOpen(data)
var declaredSyms = initHashSet[string]()
var usedSyms = initHashSet[string]()
if stream != nil:
declaredSyms.incl "section" # special case for 'section(RULE)' in the grammar
var
L: TLexer
tok: TToken
initToken(tok)
openLexer(L, f, stream, cache, config)
# load the first token:
rawGetTok(L, tok)
var word = ""
while tok.tokType != tkEof:
#printTok(config, tok)
if isKeyword(tok.tokType) or tok.tokType == tkSymbol:
word = tok.ident.s
rawGetTok(L, tok)
if tok.tokType == tkEquals:
declaredSyms.incl word
rawGetTok(L, tok)
elif not allCharsInSet(word, {'A'..'Z', '0'..'9', '_'}):
usedSyms.incl word
else:
rawGetTok(L, tok)
for u in usedSyms:
if u notin declaredSyms:
echo "Undeclared non-terminal: ", u
closeLexer(L)
else:
rawMessage(config, errGenerated, "cannot open file: " & f.string)
proc checkGrammarFile* =
checkGrammarFileImpl(newIdentCache(), newConfigRef())