RubixDev / ebnf

Various tools for EBNF grammars
GNU General Public License v3.0
8 stars 0 forks source link

No highlight for ebnf file in Neovim+nvim-treesitter #1

Closed rltyty closed 7 months ago

rltyty commented 7 months ago

Open an ebnf file syntax.ebnf in Nvim, there is no highlight, and the editor doesn't recognize the file type for there's no ebnf label in the statusline. Is there any configuration I missed ? Thanks in advance.

Test environment ## nvim `nvim --version NVIM v0.9.5` ## Installation ebnf treesitter plugin `:TSInstall ebnf ` ## checkhealth `:checkhealth nvim-treesitter` ``` nvim-treesitter: require("nvim-treesitter.health").check() Installation ~ - OK `tree-sitter` found 0.20.8 (parser generator, only needed for :TSInstallFromGrammar) - OK `node` found v21.4.0 (only needed for :TSInstallFromGrammar) - OK `git` executable found. - OK `cc` executable found. Selected from { vim.NIL, "cc", "gcc", "clang", "cl", "zig" } Version: Apple clang version 14.0.0 (clang-1400.0.29.202) - OK Neovim was compiled with tree-sitter runtime ABI version 14 (required >=13). Parsers must be compatible with runtime ABI. OS Info: { machine = "x86_64", release = "21.6.0", sysname = "Darwin", version = "Darwin Kernel Version 21.6.0: Thu Nov 9 00:38:19 PST 2023; root:xnu-8020.240.18.705.10~1/RELEASE_X86_64" } ~ Parser/Features H L F I J - bash ✓ ✓ ✓ . ✓ - c ✓ ✓ ✓ ✓ ✓ - diff ✓ . . . . - ebnf ✓ . . . . - html ✓ ✓ ✓ ✓ ✓ - javascript ✓ ✓ ✓ ✓ ✓ - jsdoc ✓ . . . . - json ✓ ✓ ✓ ✓ . - jsonc ✓ ✓ ✓ ✓ ✓ - lua ✓ ✓ ✓ ✓ ✓ - luadoc ✓ . . . . - luap ✓ . . . . - markdown ✓ . ✓ ✓ ✓ - markdown_inline ✓ . . . ✓ - python ✓ ✓ ✓ ✓ ✓ - query ✓ ✓ ✓ ✓ ✓ - regex ✓ . . . . - toml ✓ ✓ ✓ ✓ ✓ - tsx ✓ ✓ ✓ ✓ ✓ - typescript ✓ ✓ ✓ ✓ ✓ - vim ✓ ✓ ✓ . ✓ - vimdoc ✓ . . . ✓ - yaml ✓ ✓ ✓ ✓ ✓ Legend: H[ighlight], L[ocals], F[olds], I[ndents], In[j]ections +) multiple parsers found, only one will be used x) errors found in the query, try to run :TSUpdate {lang} ~ ``` ## A ebnf file "syntax.ebnf" ``` chunk ::= block block ::= {stat} [retstat] stat ::= ‘;’ | varlist ‘=’ explist | functioncall | label | break | goto Name | do block end | while exp do block end | repeat block until exp | if exp then block {elseif exp then block} [else block] end | for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end | for namelist in explist do block end | function funcname funcbody | local function Name funcbody | local attnamelist [‘=’ explist] attnamelist ::= Name attrib {‘,’ Name attrib} attrib ::= [‘<’ Name ‘>’] retstat ::= return [explist] [‘;’] label ::= ‘::’ Name ‘::’ funcname ::= Name {‘.’ Name} [‘:’ Name] varlist ::= var {‘,’ var} var ::= Name | prefixexp ‘[’ exp ‘]’ | prefixexp ‘.’ Name namelist ::= Name {‘,’ Name} explist ::= exp {‘,’ exp} exp ::= nil | false | true | Numeral | LiteralString | ‘...’ | functiondef | prefixexp | tableconstructor | exp binop exp | unop exp prefixexp ::= var | functioncall | ‘(’ exp ‘)’ functioncall ::= prefixexp args | prefixexp ‘:’ Name args args ::= ‘(’ [explist] ‘)’ | tableconstructor | LiteralString functiondef ::= function funcbody funcbody ::= ‘(’ [parlist] ‘)’ block end parlist ::= namelist [‘,’ ‘...’] | ‘...’ tableconstructor ::= ‘{’ [fieldlist] ‘}’ fieldlist ::= field {fieldsep field} [fieldsep] field ::= ‘[’ exp ‘]’ ‘=’ exp | Name ‘=’ exp | exp fieldsep ::= ‘,’ | ‘;’ binop ::= ‘+’ | ‘-’ | ‘*’ | ‘/’ | ‘//’ | ‘^’ | ‘%’ | ‘&’ | ‘~’ | ‘|’ | ‘>>’ | ‘<<’ | ‘..’ | ‘<’ | ‘<=’ | ‘>’ | ‘>=’ | ‘==’ | ‘~=’ | and | or unop ::= ‘-’ | not | ‘#’ | ‘~’ ```
RubixDev commented 7 months ago

The README states:

This parser implements the EBNF syntax as described by the ISO/IEC 14977:1996 standard with two notable differences:

  1. The ISO standard does not allow underscores _ in meta-identifiers
  2. The ISO standard only allows characters from the ISO/IEC 646:1991 character set

The example syntax you provided does not follow the ISO specification and is therefore not parsed correctly.

This should be what your syntax looks like using the ISO specification ```ebnf chunk = block ; block = { stat } , [ retstat ] ; stat = ';' | varlist , '=' , explist | functioncall | label | 'break' | 'goto' , Name | 'do' , block , 'end' | 'while' , exp , 'do' , block , 'end' | 'repeat' , block , 'until' , exp | 'if' , exp , 'then' , block , { 'elseif' , exp , 'then' , block } , [ 'else' , block ] , 'end' | 'for' , Name , '=' , exp , ',' , exp , [ ',' , exp ] , 'do' , block , 'end' | 'for' , namelist , 'in' , explist , 'do' , block , 'end' | 'function' , funcname , funcbody | 'local' , 'function' , Name , funcbody | 'local' , attnamelist , [ '=' , explist ] ; attnamelist = Name , attrib , { ',' , Name , attrib } ; attrib = [ '<' , Name , '>' ] ; retstat = 'return' , [ explist ] , [ ';' ] ; label = '::' , Name , '::' ; funcname = Name , { '.' , Name } , [ ':' , Name ] ; varlist = var , { ',' , var } ; var = Name | prefixexp , '[' , exp , ']' , | prefixexp , '.' , Name ; namelist = Name , { ',' , Name } ; explist = exp , { ',' , exp } ; exp = 'nil' | 'false' | 'true' | Numeral | LiteralString | '...' | functiondef | prefixexp | tableconstructor | exp , binop , exp | unop , exp ; prefixexp = var | functioncall | '(' , exp , ')' ; functioncall = prefixexp , args | prefixexp , ':' , Name , args ; args = '(' , [ explist ] , ')' | tableconstructor | LiteralString ; functiondef = 'function' , funcbody ; funcbody = '(' , [ parlist ] , ')' , block , 'end' ; parlist = namelist , [ ',' , '...' ] | '...' ; tableconstructor = '{' , [ fieldlist ] , '}' ; fieldlist = field , { fieldsep , field } , [ fieldsep ] ; field = '[' , exp , ']' , '=' , exp | Name , '=' , exp | exp ; fieldsep = ',' | ';' ; binop = '+' | '-' | '*' | '/' | '//' | '^' | '%' | '&' | '~' | '|' | '>>' | '<<' | '..' | '<' | '<=' | '>' | '>=' | '==' | '~=' | 'and' | 'or' ; unop = '-' | 'not' | '#' | '~' ; ```

However, even with your syntax file you should still get some highlighting. Please make sure you have the ebnf file type registered in Neovim (I don't think it is by default). Use this Lua snippet to associate the ebnf file extension with an ebnf file type (also described in the README):

vim.filetype.add { extension = { ebnf = 'ebnf' } }

If that doesn't help, run the :Inspect command while your cursor is on an identifier. The output should look similar to this:

Treesitter
  - @string.special.symbol.ebnf links to @string.special.symbol ebnf

I understand that there are multiple different "versions" of EBNF notation and that this parser is somewhat limiting in only allowing the ISO version, but I don't have any immediate plans to try to support multiple versions in this parser.

rltyty commented 7 months ago

Many thanks @RubixDev , after ebnf extension being registered to vim.filetype, my Nvim can now recognize ebnf files. And the highlighting looks better in your "version" of syntax.