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;