module Savi::Parser

Defined in:

savi/parser.cr
savi/parser/grammar.cr

Constant Summary

Grammar = Pegmatite::DSL.define do eol_annotation = ((str("::")) >> (char(' ')).maybe) >> (((~(char('\n'))) >> any).repeat.named(:annotation)) eol_comment = ((str("//")) >> ((~(char('\n'))) >> any).repeat) | eol_annotation whitespace = ((((char(' ')) | (char('\t'))) | (char('\r'))) | (str("\\\n"))) | (str("\\\r\n")) s = whitespace.repeat newline = (s >> eol_comment.maybe) >> ((char('\n')) | s.then_eof) sn = (whitespace | newline).repeat digit19 = range('1', '9') digit = range('0', '9') digithex = (digit | (range('a', 'f'))) | (range('A', 'F')) digitbin = range('0', '1') numsep = char('_') digits = digit >> (digit | numsep).repeat int = (((((((str("0x")) >> digithex) >> (digithex | numsep).repeat) | (((str("0b")) >> digitbin) >> (digitbin | numsep).repeat)) | (((char('-')) >> digit19) >> (digit | numsep).repeat)) | ((char('-')) >> (char('0')))) | (digit19 >> (digit | numsep).repeat)) | (char('0')) frac = (char('.')) >> digits exp = (((char('e')) | (char('E'))) >> ((char('+')) | (char('-'))).maybe) >> digits integer = int.named(:integer) float = (int >> ((frac >> exp.maybe) | exp)).named(:float) ident_letter = (((range('a', 'z')) | (range('A', 'Z'))) | (range('0', '9'))) | (char('_')) ident = (((((char('@')) >> ident_letter.repeat) | (((char('^')) >> digit19) >> digit.repeat)) | (ident_letter.repeat(1))) >> (char('!')).maybe).named(:ident) parens = declare() string_char = ((((((((((((((((((((((str("\\'")) | (str("\\\""))) | (str("\\\\"))) | (str("\\b"))) | (str("\\f"))) | (str("\\n"))) | (str("\\r"))) | (str("\\t"))) | (str("\\v"))) | (str("\\0"))) | (str("\b"))) | (str("\f"))) | (str("\n"))) | (str("\r"))) | (str("\t"))) | (str("\v"))) | (str("\u0000"))) | (((str("\\x")) >> digithex) >> digithex)) | (((((str("\\u")) >> digithex) >> digithex) >> digithex) >> digithex)) | (((((((((str("\\U")) >> digithex) >> digithex) >> digithex) >> digithex) >> digithex) >> digithex) >> digithex) >> digithex)) | ((((char('\\')) >> (char('\r')).maybe) >> (char('\n'))) >> s)) | (((str("\\")) >> (~(~(char('('))))) >> parens)) | ((str("\\")).maybe >> (((~(char('"'))) >> (~(char('\\')))) >> (range(' ', 1114111_u32)))) string = ((((ident_letter.named(:ident)).maybe >> (char('"'))) >> (string_char.repeat.named(:string))) >> (char('"'))).named(:string) character_char = ((((((((((((((((((((str("\\'")) | (str("\\\""))) | (str("\\\\"))) | (str("\\b"))) | (str("\\f"))) | (str("\\n"))) | (str("\\r"))) | (str("\\t"))) | (str("\\v"))) | (str("\\0"))) | (str("\b"))) | (str("\f"))) | (str("\n"))) | (str("\r"))) | (str("\t"))) | (str("\v"))) | (str("\u0000"))) | (((str("\\x")) >> digithex) >> digithex)) | (((((str("\\u")) >> digithex) >> digithex) >> digithex) >> digithex)) | (((((((((str("\\U")) >> digithex) >> digithex) >> digithex) >> digithex) >> digithex) >> digithex) >> digithex) >> digithex)) | (((~(char('\''))) >> (~(char('\\')))) >> (range(' ', 1114111_u32))) character = ((char('\'')) >> (character_char.repeat.named(:char))) >> (char('\'')) heredoc_content = declare() heredoc = ((str("<<<")) >> (heredoc_content.named(:heredoc))) >> (str(">>>")) heredoc_no_token = ((str("<<<")) >> heredoc_content) >> (str(">>>")) heredoc_content.define((heredoc_no_token | ((~(str(">>>"))) >> any)).repeat) anystring = (string | character) | heredoc atom = (((parens | anystring) | float) | integer) | ident opcap = (char('\'')).named(:op) opdot = (char('.')).named(:op) oparrow = (str("->")).named(:op) compound_without_prefix = ((atom >> ((((opcap >> ident) | (((s >> oparrow) >> s) >> atom)) | (((sn >> opdot) >> sn) >> atom)) | parens).repeat) >> (s >> eol_annotation).maybe).named(:compound) prefixop = (((str("--")) | (char('!'))) | (char('~'))).named(:op) compound_with_prefix = (prefixop >> compound_without_prefix).named(:prefix) compound = compound_with_prefix | compound_without_prefix opw = ((char(' ')) | (char('\t'))) op1 = ((((str("*!")) | (char('*'))) | (char('/'))) | (char('%'))).named(:op) op2 = ((((str("+!")) | (str("-!"))) | (char('+'))) | (char('-'))).named(:op) op3 = (((((((((((((((((((str("<|>")) | (str("<~>"))) | (str("<<~"))) | (str("~>>"))) | (str("<<"))) | (str(">>"))) | (str("<~"))) | (str("~>"))) | (str("<:"))) | (str("!<:"))) | (str(">="))) | (str("<="))) | (char('<'))) | (char('>'))) | (str("==="))) | (str("=="))) | (str("!=="))) | (str("!="))) | (str("=~"))).named(:op) op4 = ((str("&&")) | (str("||"))).named(:op) ope = ((((((str("+=")) | (str("-="))) | (str("*="))) | (str("/="))) | (str("<<="))) | (char('='))).named(:op) ope_colon = (char(':')).named(:op) t1 = compound t2 = (t1 >> (((sn >> op1) >> sn) >> t1).repeat).named(:relate) t3 = (t2 >> (((sn >> op2) >> sn) >> t2).repeat).named(:relate) t4 = (t3 >> (((sn >> op3) >> sn) >> t3).repeat).named(:relate) tw = (t4 >> (((sn >> op4) >> sn) >> t4).repeat).named(:relate) te = (((tw >> (((opw >> s) >> tw).repeat(1))).named(:group_w)) >> s) | tw t = ((te >> (((s >> (ope_colon | (sn >> ope))) >> sn) >> te).repeat).named(:relate_assign)) >> s decl = declare() term = decl | t termsl = ((term >> s) >> ((((char(',')) >> sn) >> term) >> s).repeat) >> ((char(',')) >> s).maybe terms = (termsl >> sn).repeat pipesep = (char('|')).named(:op) ptermsp = (((((pipesep.maybe >> sn) >> (((terms >> sn) >> pipesep) >> sn).repeat) >> terms) >> sn) >> pipesep.maybe) >> sn parens.define(((((((char('(')) >> sn) >> ptermsp.maybe) >> sn) >> (char(')'))).named(:group)) | (((((((char('[')) >> sn) >> ptermsp.maybe) >> sn) >> (char(']'))) >> (char('!')).maybe).named(:group))) decl.define((((((char(':')) >> ident) >> (s >> compound).repeat) >> s).named(:decl)) >> ((char(':')) | (~(~newline)))) doc = (sn >> terms).named(:doc) doc.then_eof end

Class Method Summary

Class Method Detail

def self.parse(source : Source) #

[View source]