Python API tutorial 4: lexers and lexemes¶
Most scripts work with the entities and references stored in the database, but sometimes you need the raw text of a file token by token. Understand gives you that through a file's lexer and the lexeme objects it yields.
- Lexeme — a chunk of text that means something to the parser: a keyword, an identifier, a string, a comment, punctuation, and so on.
- Lexer (
understand.Lexer) — a stream of lexemes for a file.
Walking the stream, you can ask each lexeme for its text, its token type (Comment, Punctuation,
Preprocessor, Identifier, …), the entity or reference
it's associated with, and the line it's on.
Opening a lexer¶
Get a lexer from a file entity with file.lexer(...). The parameters, in order, are:
| Parameter | Default | Meaning |
|---|---|---|
lookup_ents |
True |
Associate lexemes with entities/references |
tabstop |
1 |
Deprecated — accepted for backward compatibility but ignored; tabs always count as 1 column |
show_inactive |
True |
Include code disabled by the preprocessor |
expand_macros |
False |
Expand macros in the token stream |
Example: clean text of a file¶
Return a file's text with comments removed, inactive (preprocessed-out) code removed, and macros expanded:
import understand
db = understand.open("C:/sample project/sample_project.und")
def fileCleanText(file):
returnString = ""
# Open the file lexer with macros expanded and inactive code removed
for lexeme in file.lexer(False, 1, False, True):
if lexeme.token() != "Comment":
# Append the text of every non-comment lexeme
returnString += lexeme.text()
return returnString
# Find the first file whose name contains 'test', then print it and its cleaned text
file = db.lookup(".test.", "file")[0]
print(file.longname())
print(fileCleanText(file))
How it works:
file.lexer(False, 1, False, True)opens the lexer withlookup_ents=False,tabstop=1(ignored — kept only for signature compatibility),show_inactive=False(drop inactive code), andexpand_macros=True(expand macros).- Iterating the lexer yields each
Lexeme.lexeme.token()returns the token type as a string, andlexeme.text()returns the raw text. db.lookup(".test.", "file")looks up entities by name — the name argument is a regular expression, so.test.matches any file whose name containstest. It returns a list;[0]takes the first match.
lookup() returns a list
db.lookup(...) can return an empty list. Guard the [0] (or check len(...)) before indexing if
the name might not match anything.
Next¶
You can now read source at the token level. Next you'll turn a script into a plugin that draws a graph.
← Tutorial 3: entities, references, and filters · → Tutorial 5: graphs