Skip to content

Grammar railroad diagram #22

@mingodad

Description

@mingodad

While trying to visualize this project grammar as a railroad diagram using https://mingodad.github.io/plgh/json2ebnf.html I've noticed that you are using invalid regexes in several places (see bellow commented rules), tree-sitter doesn't accept lookahead/lookbehind in regexes see here https://tree-sitter.github.io/tree-sitter/creating-parsers/2-the-grammar-dsl.html .

//
// EBNF to generate railroad diagram at
//      (IPV6) https://www.bottlecaps.de/rr/ui
//      (IPV4) https://rr.red-dove.com/ui
//
// From https://raw.githubusercontent.com/getgrit/tree-sitter-gritql/refs/heads/main/src/grammar.json
//

source_file ::=
	 version? langdecl? ( definition ( '\n'  definition )* '\n' ? )? _pattern? ( definition ( '\n'  definition )* '\n' ? )?

sequential ::=
	 'sequential' '{' ( _pattern ( ',' _pattern )* ','? ) '}'

files ::=
	 'multifile' '{' ( _pattern ( ',' _pattern )* ','? ) '}'

definition ::=
	 patternDefinition
	| predicateDefinition
	| functionDefinition
	| foreignFunctionDefinition

version ::=
	 'engine ' 'marzano' '(' doubleConstant ')'

language_flavor ::=
	 ( 'flow' | 'flowComments' | 'typescript' | 'jsx' | 'js_do_not_use' | 'inline' | 'block' | 'only' | 'html' )

langdecl ::=
	 'language' languageName ( '(' language_flavor ')' ';'? )?

_pattern ::=
	 _literal | patternNot | patternOr | patternOrElse | patternAny | patternAnd | patternMaybe | patternIfElse | patternContains | patternIncludes | patternAfter | patternBefore | within | bubble | nodeLike | mapAccessor | listIndex | dot | some | every | underscore | variable | regexPattern | patternAs | patternLimit | assignmentAsPattern | patternAccumulate | rewrite | like | log | range | patternWhere | mulOperation | divOperation | modOperation | addOperation | subOperation | sequential | files | '(' _pattern ')'

_container ::=
	 variable
	| mapAccessor
	| listIndex

mulOperation ::=
	 _pattern '*' _pattern

divOperation ::=
	 _pattern '/' _pattern

modOperation ::=
	 _pattern '%' _pattern

addOperation ::=
	 _pattern '+' _pattern

subOperation ::=
	 _pattern '-' _pattern

patternAs ::=
	 _pattern 'as' variable

patternLimit ::=
	 _pattern 'limit' intConstant

assignmentAsPattern ::=
	 _container '=' _pattern

patternAccumulate ::=
	 _pattern '+=' _pattern

patternWhere ::=
	 _pattern 'where' _predicate

_literal ::=
	 codeSnippet
	| top
	| bottom
	| stringConstant
	| intConstant
	| doubleConstant
	| booleanConstant
	| undefined
	| map
	| list

patternNot ::=
	 ( '!' | 'not' ) _pattern

patternOr ::=
	 'or' '{' ( _pattern ( ',' _pattern )* ','? ) '}'

patternOrElse ::=
	 'orelse' '{' ( _pattern ( ',' _pattern )* ','? )? '}'

patternAny ::=
	 'any' '{' ( _pattern ( ',' _pattern )* ','? )? '}'

patternAnd ::=
	 'and' '{' ( _pattern ( ',' _pattern )* ','? )? '}'

patternMaybe ::=
	 'maybe' ( _pattern | '{' _pattern '}' )

patternAfter ::=
	 'after' _pattern

patternBefore ::=
	 'before' _pattern

patternContains ::=
	 'contains' ( _pattern | '{' _pattern '}' ) ( 'until' _pattern )?

patternIncludes ::=
	 'includes' ( _pattern | '{' _pattern '}' )

rewrite ::=
	 _pattern annotation? '=>' _pattern

patternIfElse ::=
	 'if' '(' _predicate ')' ( _pattern | '{' _pattern '}' ) ( 'else' ( _pattern | '{' _pattern '}' ) )?

within ::=
	 'within' ( _pattern | '{' _pattern '}' ) ( 'until' _pattern )?

_bubbleScope ::=
	 'bubble' ( '(' ( variable ( ',' variable )* ','? )? ')' )?

bubble ::=
	 _bubbleScope ( _pattern | '{' _pattern '}' )

namedArg ::=
	 _pattern
	| name '=' _pattern

nodeLike ::=
	 name '(' ( namedArg ( ',' namedArg )* ','? )? ')'

like ::=
	 'like' ( '(' _pattern ')' )? '{' _pattern '}'

map ::=
	 '{' ( mapElement ( ',' mapElement )* ','? )? '}'

mapElement ::=
	 name ':' _pattern

mapAccessor ::=
	 ( map | _container ) '.' ( name | variable )

list ::=
	 name? '[' ( ( _pattern | dotdotdot ) ( ',' ( _pattern | dotdotdot ) )* ','? )? ']'

listIndex ::=
	 ( list | _container ) '[' ( _container | signedIntConstant ) ']'

dot ::=
	 '.'

some ::=
	 'some' ( _pattern | '{' _pattern '}' )

every ::=
	 'every' ( _pattern | '{' _pattern '}' )

dotdotdot ::=
	 '\$'?'...\'*? ( _pattern | '{' _pattern '}' )?

underscore ::=
	 '$_'

regexPattern ::=
	 ( regex | snippetRegex ) ( '(' ( variable ( ',' variable )* ','? )? ')' )?

patternDefinitionBody ::=
	 '{' ( _pattern ( ',' _pattern )* ','? )? '}'

patternDefinition ::=
	 'private'? 'pattern ' name '(' ( variable ( ',' variable )* ','? )? ')' langdecl? patternDefinitionBody

predicateDefinitionBody ::=
	 '{' ( _predicate ( ',' _predicate )* ','? )? '}'

predicateDefinition ::=
	 'predicate ' name '(' ( variable ( ',' variable )* ','? )? ')' predicateDefinitionBody

//noBraces ::=
//	 (?':"'(?':'[^"\]|'\.')*'"')|(?":'"(?":"[^'\]|"\.")*"'")|(?":`"(?":"[^`\]|"\.")*"`")|([^{}"`'#x0D#x0A]+)

foreignLanguageCode ::=
	 ( noBraces | comment | '{' foreignLanguageCode '}' )+

foreignFunctionBody ::=
	 '{' foreignLanguageCode '}'

functionDefinitionBody ::=
	 '{' ( _predicate ( ',' _predicate )* ','? )? '}'

functionDefinition ::=
	 'function ' name '(' ( variable ( ',' variable )* ','? )? ')' functionDefinitionBody

foreignFunctionDefinition ::=
	 'function ' name '(' ( variable ( ',' variable )* ','? )? ')' foreignLanguageName foreignFunctionBody

_logMessage ::=
	 'message' '=' ( stringConstant | variable )
	| '$message'

_logVariable ::=
	 'variable' '=' variable
	| variable

log ::=
	 'log(' ( _logMessage | _logVariable | _logMessage ',' _logVariable | _logVariable ',' _logMessage ) ','? ')'

_start_line ::=
	 'start_line' '=' intConstant

_end_line ::=
	 'end_line' '=' intConstant

_start_column ::=
	 'start_column' '=' intConstant

_end_column ::=
	 'end_column' '=' intConstant

range ::=
	 'range(' ( _start_line | _end_line | _start_column | _end_column | _start_line ',' _end_line | _end_line ',' _start_line | _start_line ',' _start_column | _start_column ',' _start_line | _start_line ',' _end_column | _end_column ',' _start_line | _start_column ',' _end_line | _end_line ',' _start_column | _end_column ',' _end_line | _end_line ',' _end_column | _start_column ',' _end_column | _end_column ',' _start_column | _end_line ',' _start_column ',' _end_column | _end_line ',' _end_column ',' _start_column | _start_column ',' _end_line ',' _end_column | _start_column ',' _end_column ',' _end_line | _end_column ',' _end_line ',' _start_column | _end_column ',' _start_column ',' _end_line | _start_line ',' _start_column ',' _end_column | _start_line ',' _end_column ',' _start_column | _start_column ',' _start_line ',' _end_column | _start_column ',' _end_column ',' _start_line | _end_column ',' _start_line ',' _start_column | _end_column ',' _start_column ',' _start_line | _end_line ',' _start_line ',' _end_column | _end_line ',' _end_column ',' _start_line | _start_line ',' _end_line ',' _end_column | _start_line ',' _end_column ',' _end_line | _end_column ',' _end_line ',' _start_line | _end_column ',' _start_line ',' _end_line | _end_line ',' _start_column ',' _start_line | _end_line ',' _start_line ',' _start_column | _start_column ',' _end_line ',' _start_line | _start_column ',' _start_line ',' _end_line | _start_line ',' _end_line ',' _start_column | _start_line ',' _start_column ',' _end_line | _start_line ',' _end_line ',' _start_column ',' _end_column | _start_line ',' _end_line ',' _end_column ',' _start_column | _start_line ',' _start_column ',' _end_line ',' _end_column | _start_line ',' _start_column ',' _end_column ',' _end_line | _start_line ',' _end_column ',' _end_line ',' _start_column | _start_line ',' _end_column ',' _start_column ',' _end_line | _end_line ',' _start_line ',' _start_column ',' _end_column | _end_line ',' _start_line ',' _end_column ',' _start_column | _end_line ',' _start_column ',' _start_line ',' _end_column | _end_line ',' _start_column ',' _end_column ',' _start_line | _end_line ',' _end_column ',' _start_line ',' _start_column | _end_line ',' _end_column ',' _start_column ',' _start_line | _start_column ',' _end_line ',' _start_line ',' _end_column | _start_column ',' _end_line ',' _end_column ',' _start_line | _start_column ',' _start_line ',' _end_line ',' _end_column | _start_column ',' _start_line ',' _end_column ',' _end_line | _start_column ',' _end_column ',' _end_line ',' _start_line | _start_column ',' _end_column ',' _start_line ',' _end_line | _end_column ',' _end_line ',' _start_column ',' _start_line | _end_column ',' _end_line ',' _start_line ',' _start_column | _end_column ',' _start_column ',' _end_line ',' _start_line | _end_column ',' _start_column ',' _start_line ',' _end_line | _end_column ',' _start_line ',' _end_line ',' _start_column | _end_column ',' _start_line ',' _start_column ',' _end_line ) ','? ')'

_predicate ::=
	 predicateNot
	| predicateMaybe
	| predicateAnd
	| predicateOr
	| predicateAny
	| predicateIfElse
	| predicateAssignment
	| predicateAccumulate
	| predicateRewrite
	| log
	| predicateGreater
	| predicateLess
	| predicateGreaterEqual
	| predicateLessEqual
	| predicateNotEqual
	| predicateEqual
	| predicateMatch
	| predicateCall
	| '(' _predicate ')'
	| booleanConstant
	| predicateReturn

predicateNot ::=
	 ( 'not' | '!' ) _predicate

predicateMaybe ::=
	 'maybe' _predicate

predicateAnd ::=
	 'and'? '{' ( _predicate ( ',' _predicate )* ','? )? '}'

predicateOr ::=
	 'or' '{' ( _predicate ( ',' _predicate )* ','? )? '}'

predicateAny ::=
	 'any' '{' ( _predicate ( ',' _predicate )* ','? )? '}'

predicateIfElse ::=
	 'if' '(' _predicate ')' _predicate ( 'else' _predicate )?

predicateRewrite ::=
	 variable annotation? '=>' _pattern

predicateAssignment ::=
	 _container '=' _pattern

predicateAccumulate ::=
	 variable '+=' _pattern

predicateGreater ::=
	 variable '>' _pattern

predicateLess ::=
	 variable '<' _pattern

predicateGreaterEqual ::=
	 variable '>=' _pattern

predicateLessEqual ::=
	 variable '<=' _pattern

predicateNotEqual ::=
	 variable '!=' _pattern

predicateEqual ::=
	 variable '==' _pattern

predicateMatch ::=
	 ( _container | _literal ) '<:' _pattern

predicateCall ::=
	 name '(' ( namedArg ( ',' namedArg )* ','? )? ')'

predicateReturn ::=
	 'return' _pattern

booleanConstant ::=
	 ( 'true' | 'false' )

variable ::=
	 [\$\^][A-Za-z0-9_]*

name ::=
	 [\^#x23A-Za-z_][A-Za-z0-9_]*

foreignLanguageName ::=
	 'js'

languageName ::=
	 'grit'
	| 'js'
	| 'html'
	| 'css'
	| 'json'
	| 'java'
	| 'csharp'
	| 'python'
	| 'go'
	| 'markdown'
	| 'rust'
	| 'ruby'
	| 'sol'
	| 'solidity'
	| 'hcl'
	| 'yaml'
	| 'ast'
	| 'universal'
	| 'sql'
	| 'toml'
	| 'php'
	| 'c'
	| 'ruby'
	| 'cpp'
	| 'kotlin'
	| 'elixir'

//backtickSnippet ::=
//	 '`'(?':'[^`\]|'\\$'|'\\'|'\`'|'\n')*'`'

//rawBacktickSnippet ::=
//	 'raw`'(?':'[^`\]|'\\$'|'\\'|'\`'|'\n')*'`'

//doubleQuoteSnippet ::=
//	 '"'(?':'[^"\]|'\\$'|'\\'|'\"'|'\n')*'"'

languageSpecificSnippet ::=
	 languageName doubleQuoteSnippet

codeSnippet ::=
	 ( backtickSnippet | languageSpecificSnippet | rawBacktickSnippet )

undefined ::=
	 'undefined'

top ::=
	 'Top'

bottom ::=
	 'Bottom'

intConstant ::=
	 [0-9]+

signedIntConstant ::=
	 '-'?[0-9]+

doubleConstant ::=
	 [+-]?[0-9]+'.'[0-9]+([eE][+-]?[0-9]+)?

//stringConstant ::=
//	 '"'(?':'[^"\]|'\.')*'"'

//regex ::=
//	 'r"'(?':'[^"\]|'\.')*'"'

snippetRegex ::=
	 'r' backtickSnippet

annotation ::=
	 '@'[A-Za-z][A-Za-z0-9]*

_separator ::=
	 ( ',' | '\n'  )

comment ::=
	 ( '//' '.'* | '/*' [^*]*'\'*+([^/*][^*]*'\'*+)* '/' )

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions