1// Copyright (C) 2025 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15import { 16 LRLanguage, 17 LanguageSupport, 18 delimitedIndent, 19 foldInside, 20 foldNodeProp, 21 indentNodeProp, 22} from '@codemirror/language'; 23import {styleTags, tags as t} from '@lezer/highlight'; 24import {parser} from './perfetto_sql.grammar'; // Generated by Lezer 25import {TreeCursor} from '@lezer/common'; 26 27export const language = LRLanguage.define({ 28 parser: parser.configure({ 29 props: [ 30 indentNodeProp.add({ 31 Application: delimitedIndent({closing: ')', align: false}), 32 }), 33 foldNodeProp.add({ 34 Application: foldInside, 35 }), 36 styleTags({ 37 'Keyword': t.keyword, 38 'Boolean': t.bool, 39 'String': t.string, 40 'Number': t.number, 41 'LineComment': t.lineComment, 42 'Macro': t.macroName, 43 'MacroVariable': t.variableName, 44 'Function': t.function(t.variableName), 45 '( )': t.paren, 46 }), 47 ], 48 }), 49 languageData: { 50 commentTokens: {line: '--'}, 51 }, 52}); 53 54export function perfettoSql() { 55 return new LanguageSupport(language); 56} 57 58export function parseAndPrintTree(code: string) { 59 const tree = language.parser.parse(code); 60 const cursor = tree.cursor(); 61 printCST(cursor, code); 62} 63 64// Helper function to pretty-print the CST 65function printCST(cursor: TreeCursor, source: string, indent = 0) { 66 const nodeName = cursor.name; 67 const nodeText = source.substring(cursor.from, cursor.to); 68 69 console.log(`${' '.repeat(indent)}${nodeName}: "${nodeText}"`); 70 71 if (cursor.firstChild()) { 72 do { 73 printCST(cursor, source, indent + 1); 74 } while (cursor.nextSibling()); 75 cursor.parent(); // Important: Move back up to the parent 76 } 77} 78