mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-30 18:02:05 +00:00
48 lines
1.4 KiB
Nim
48 lines
1.4 KiB
Nim
## 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: Lexer
|
|
tok: Token
|
|
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())
|