blob: 3bcc4757792d49b7c23d75e3c990d06f15322f30 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include "Builtin.h"
#include <stdarg.h>
#include <stdlib.h>
#define ref(name) ExpressionNewValue(IdentExpr,name)
#define seq(...) makeExpression(SequenceExpr,__VA_ARGS__,NULL)
#define choice(...) makeExpression(ChoiceExpr,__VA_ARGS__,NULL)
#define and(...) makeExpression(AndExpr,__VA_ARGS__,NULL)
#define not(...) makeExpression(NotExpr,__VA_ARGS__,NULL)
#define opt(...) makeExpression(OptExpr,__VA_ARGS__,NULL)
#define star(...) makeExpression(StarExpr,__VA_ARGS__,NULL)
#define plus(...) makeExpression(PlusExpr,__VA_ARGS__,NULL)
#define lit(value) ExpressionNewValue(LitExpr,value)
#define cls(...) makeExpression(ClassExpr,__VA_ARGS__,NULL)
#define dot() makeExpression(DotExpr,NULL)
#define range(lo,hi) ExpressionNewRange(lo,hi)
static Expression *makeExpression(ExprKind kind, ...)
{
Expression *children[20];
int count = 0;
va_list ap;
va_start(ap,kind);
Expression *expr;
while ((count < 20) && ((expr = va_arg(ap,Expression *)) != NULL))
children[count++] = expr;
va_end(ap);
return ExpressionNew(kind,count,children);
}
Grammar *GrammarNewBuiltin(void)
{
Grammar *gram = GrammarNew();
// Grammar <- Spacing Definition+ EndOfFile
GrammarDefine(gram,"Grammar",
seq(ref("Spacing"),
plus(ref("Definition")),
ref("EndOfFile")));
// Definition <- Identifier LEFTARROW Expression
GrammarDefine(gram,"Definition",
seq(ref("Identifier"),
ref("LEFTARROW"),
ref("Expression")));
// Expression <- Sequence (SLASH Sequence)*
GrammarDefine(gram,"Expression",
seq(ref("Sequence"),
star(seq(ref("SLASH"),ref("Sequence")))));
// Sequence <- Prefix*
GrammarDefine(gram,"Sequence",
star(ref("Prefix")));
// Prefix <- (AND / NOT)? Suffix
GrammarDefine(gram,"Prefix",
seq(opt(choice(ref("AND"),
ref("NOT"))),
ref("Suffix")));
// Suffix <- Primary (QUESTION / STAR / PLUS)?
GrammarDefine(gram,"Suffix",
seq(ref("Primary"),
opt(choice(ref("QUESTION"),
ref("STAR"),
ref("PLUS")))));
// Primary <- Identifier !LEFTARROW
// / OPEN Expression CLOSE
// / Literal
// / Class
// / DOT
GrammarDefine(gram,"Primary",
choice(seq(ref("Identifier"),not(ref("LEFTARROW"))),
seq(ref("OPEN"),ref("Expression"),ref("CLOSE")),
ref("Literal"),
ref("Class"),
ref("DOT")));
// Identifier <- IdentStart IdentCont* Spacing
GrammarDefine(gram,"Identifier",
seq(ref("IdentStart"),
star(ref("IdentCont")),
ref("Spacing")));
// IdentStart <- [a-zA-Z_]
GrammarDefine(gram,"IdentStart",
cls(range('a','z'),
range('A','Z'),
range('_','_')));
// IdentCont <- IdentStart
// / [0-9]
GrammarDefine(gram,"IdentCont",
choice(ref("IdentStart"),
cls(range('0','9'))));
// Literal <- ['] (!['] Char)* ['] Spacing
// / ["] (!["] Char)* ["] Spacing
GrammarDefine(gram,"Literal",
choice(seq(cls(range('\'','\'')),
star(seq(not(cls(range('\'','\''))),
ref("Char"))),
cls(range('\'','\'')),
ref("Spacing")),
seq(cls(range('"','"')),
star(seq(not(cls(range('"','"'))),
ref("Char"))),
cls(range('"','"')),
ref("Spacing"))));
// Class <- '[' (!']' Range)* ']' Spacing
GrammarDefine(gram,"Class",
seq(lit("["),
star(seq(not(lit("]")),
ref("Range"))),
lit("]"),
ref("Spacing")));
// Range <- Char '-' Char
// / Char
GrammarDefine(gram,"Range",
choice(seq(ref("Char"),
lit("-"),
ref("Char")),
ref("Char")));
// Char <- '\\' [nrt'"\[\]\\]
// / '\\' [0-2] [0-7] [0-7]
// / '\\' [0-7] [0-7]?
// / !'\\' .
GrammarDefine(gram,"Char",
choice(seq(lit("\\"),
cls(range('n','n'),
range('r','r'),
range('t','t'),
range('\'','\''),
range('"','"'),
range('[','['),
range(']',']'),
range('\\','\\'))),
seq(lit("\\"),
cls(range('0','2')),
cls(range('0','7')),
cls(range('0','7'))),
seq(lit("\\"),
cls(range('0','7')),
opt(cls(range('0','7')))),
seq(not(lit("\\")),dot())));
// LEFTARROW <- '<-' Spacing
GrammarDefine(gram,"LEFTARROW",seq(lit("<-"),ref("Spacing")));
// SLASH <- '/' Spacing
GrammarDefine(gram,"SLASH",seq(lit("/"),ref("Spacing")));
// AND <- '&' Spacing
GrammarDefine(gram,"AND",seq(lit("&"),ref("Spacing")));
// NOT <- '!' Spacing
GrammarDefine(gram,"NOT",seq(lit("!"),ref("Spacing")));
// QUESTION <- '?' Spacing
GrammarDefine(gram,"QUESTION",seq(lit("?"),ref("Spacing")));
// STAR <- '*' Spacing
GrammarDefine(gram,"STAR",seq(lit("*"),ref("Spacing")));
// PLUS <- '+' Spacing
GrammarDefine(gram,"PLUS",seq(lit("+"),ref("Spacing")));
// OPEN <- '(' Spacing
GrammarDefine(gram,"OPEN",seq(lit("("),ref("Spacing")));
// CLOSE <- ')' Spacing
GrammarDefine(gram,"CLOSE",seq(lit(")"),ref("Spacing")));
// DOT <- '.' Spacing
GrammarDefine(gram,"DOT",seq(lit("."),ref("Spacing")));
// Spacing <- (Space / Comment)*
GrammarDefine(gram,"Spacing",star(choice(ref("Space"),ref("Comment"))));
// Comment <- '#' (!EndOfLine .)* EndOfLine
GrammarDefine(gram,"Comment",
seq(lit("#"),
star(seq(not(ref("EndOfLine")),
dot())),
ref("EndOfLine")));
// Space <- ' '
// / '\t'
// / EndOfLine
GrammarDefine(gram,"Space",
choice(lit(" "),
lit("\t"),
ref("EndOfLine")));
// EndOfLine <- '\r\n'
// / '\n'
// / '\r'
GrammarDefine(gram,"EndOfLine",
choice(lit("\r\n"),
lit("\n"),
lit("\r")));
// EndOfFile <- !.
GrammarDefine(gram,"EndOfFile",not(dot()));
return gram;
}