mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 22:10:33 +00:00
(cherry picked from commit fadbd8f70d)
This commit is contained in:
47
tools/grammar_nanny.nim
Normal file
47
tools/grammar_nanny.nim
Normal 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())
|
||||
Reference in New Issue
Block a user