Actions

Ontolog Forum

The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
grammar KGSQL;

/**
 * Knowledge Graph System Query Language ANTLR4 Grammar.  
 */

@header {
package kgsql.parser;
}

root : command;

command : prologue ( selectQuery | askQuery
  | constructQuery | insertRequest | deleteRequest );

prologue : prefixDecl*;

prefixDecl : Prefix NameSpace Identifier;

selectQuery : Select Variable+ whereClause;

askQuery : Ask whereClause;

constructQuery : Construct triplesBlock whereClause;

insertRequest : Insert triplesBlock whereClause;

deleteRequest : Delete Variable+ whereClause;

whereClause : Where? 
  '{' triplesBlock? ( filter '.'? triplesBlock? )* '}';

triplesBlock : triplesSameSubject ( '.' triplesBlock? )?;

filter : Filter constraint;

triplesSameSubject : ( noun | linkedList ) predicateList?;

predicateList : verb objectList ( ';' ( verb objectList )? )*;

objectList : object ( ',' object )*;

object : noun | linkedList;

noun : resourceOrVariable multiplicity? 
  | '[' resourceOrVariable resourceOrVariable? typeUnion ']'
     multiplicity?;

verb : typeUnion multiplicity? 
  | '[' resourceOrVariable typeUnion ']' multiplicity?;

typeUnion : Variable | prefixedName ( '|' prefixedName )*;

resourceOrVariable : prefixedName | typedLiteral
  | numericLiteral | True | False | Variable;

linkedList : '(' ( resourceOrVariable | linkedList )* ')' 
 | '[' '(' ( resourceOrVariable | linkedList )* ')' 
      prefixedName ']';

prefixedName : NameSpace LocalName;

constraint : '(' expression ')'
  | LocalName '(' expressionList? ')';

expressionList : expression ( ',' expression )*;

expression : conditionalAndExpression 
  ( '||' conditionalAndExpression )*;

conditionalAndExpression : relationalExpression 
  ( '&&' relationalExpression )*;

relationalExpression : additiveExpression 
  ( '=' additiveExpression 
  | '!=' additiveExpression
  | '<' additiveExpression
  | '>' additiveExpression
  | '<=' additiveExpression
  | '>=' additiveExpression )?;

additiveExpression : multiplicativeExpression
  ('+' multiplicativeExpression
  | '-' multiplicativeExpression
  | NatPositive
  | NatNegative
  | RealPositive
  | RealNegative )*;

multiplicativeExpression : unaryExpression
  ( '*' unaryExpression | '/' unaryExpression )*;

unaryExpression : primaryExpression
  | '+' primaryExpression 
  | '-' primaryExpression
  | '!' primaryExpression;

primaryExpression : '(' expression ')'
  | LocalName '(' expressionList? ')'
  | resourceOrVariable | askQuery;

typedLiteral : Literal Lang?
  | '[' Literal Lang? prefixedName ']'
  | Literal Lang? '^^' prefixedName;

numericLiteral : Nat | NatPositive | NatNegative
  | UnsignedReal | RealPositive | RealNegative;

multiplicity : '{' integer '}' | '{' integer '..' integer '}';

integer : Nat | NatPositive | NatNegative | '*';

// Lexical Scanner Tokens

// In general, KGSQL is case-sensitive,
// but the following reserved words are case-insensitive:

Prefix : [Pp][Rr][Ee][Ff][Ii][Xx] WS;
Select : [Ss][Ee][Ll][Ee][Cc][Tt] WS;
Ask : [Aa][Ss][Kk] WS;
Construct : [Cc][Oo][Nn][Ss][Tt][Rr][Uu][Cc][Tt] WS;
Insert : [Ii][Nn][Ss][Ee][Rr][Tt] WS;
Delete : [Dd][Ee][Ll][Ee][Tt][Ee] WS;
Where : [Ww][Hh][Ee][Rr][Ee];
Filter : [Ff][Ii][Ll][Tt][Ee][Rr];
True : [Tt][Rr][Uu][Ee];
False : [Ff][Aa][Ll][Ss][Ee];

// Identifiers
// The forbidden characters in an identifier are: spaces " < > \ ^ ` { | }

Identifier : '<' (~[\u0000-\u0020\u0022\u003C\u003E\u005C\u005E\u0060\u007B\u007C\u007D])* '>';

// Language Codes

Lang : '@' [a-zA-Z]+ ('-' [a-zA-Z0-9]+)*;

// Numbers

fragment UnsignedDecimal : [0-9]+ '.' [0-9]+? | '.' [0-9]+;
fragment Exponent : [eE] [+-]? [0-9]+;
fragment UnsignedDouble : [0-9]+ '.' [0-9]+? Exponent
  | '.' [0-9]+ Exponent | [0-9]+ Exponent;

Nat : [0-9]+;
NatPositive : '+' Nat;
NatNegative : '-' Nat;
UnsignedReal : UnsignedDecimal | UnsignedDouble;
RealPositive : '+' UnsignedReal;
RealNegative : '-' UnsignedReal;

// String Literals

fragment EscapedCharacter : '\\' [tbnrf'"];
fragment StringLiteral1 : '\'' ( (~[\u0027\u005C\u000A\u000D])
  | EscapedCharacter )* '\'';
fragment StringLiteral2 : '"' ( (~[\u0022\u005C\u000A\u000D])
  | EscapedCharacter )* '"';
Literal : StringLiteral1 | StringLiteral2;

// Names

fragment CharsBase : [A-Z] | [a-z] | [\u00C0-\u00D6]
  | [\u00D8-\u00F6] | [\u00F8-\u02FF] | [\u0370-\u037D]
  | [\u037F-\u1FFF] | [\u200C-\u200D] | [\u2070-\u218F]
  | [\u2C00-\u2FEF] | [\u3001-\uD7FF] | [\uF900-\uFDCF]
  | [\uFDF0-\uFFFD];
fragment CharsU : CharsBase | '_';
fragment VarName : ( CharsU | [0-9] ) ( CharsU | [0-9]
  | [\u00B7] | [\u0300-\u036F] | [\u203F-\u2040] )*;
fragment Chars : CharsU | '-' | [0-9] | [\u00B7] 
  | [\u0300-\u036F] | [\u203F-\u2040];
fragment PrefixName : CharsBase ( ( Chars | '.' )* Chars )?;

NameSpace : ':' | PrefixName ':';
LocalName : ( CharsU | [0-9] ) ( ( Chars | '.' )* Chars )?;
Variable : ( '?' | '$' ) VarName;

// Whitespace

fragment WS : (' '|'\t'|'\n'|'\r')+;
S :  WS -> skip;