-
Notifications
You must be signed in to change notification settings - Fork 37
How Do I
You do so by wrapping the body in an extra set of curly braces.
result
= char:. {{
switch (@char)
{
default:
return string.Empty;
}
}}
You have two options: partial classes or the @members
setting. The @members
setting would be used like so:
@members
{
private bool IsCharAwesome(string c)
{
return c == "a";
}
}
someRule = c:. &{ this.IsCharAwesome(c) }
Sequence expressions will return strings, unless they are typed and followed by a code expression. You can change any other expression into a sequence expression by putting an empty string at the beginning.
returnsList = other*
returnsString = "" other*
Create a rule that expects EOF (end-of-file), with an alternate case so that it doesn't find an EOF, calls #error{}
with information about what it found instead of the EOF. You probably want to wrap the captured text in Regex.Escape
so that invisible characters like newlines will be reported as \n
instead of just putting a line-break in your error message.
Report a single unexpected character:
EOF = !.
/ unexpected:.
#error{ $"Unexpected '{Regex.Escape(unexpected)}' at line {state.Line}, col {state.Column - 1}" }
Match an unexpected keyword or token (everything up to the next space/tab/newline):
EOF = !.
/ unexpected:("" [^ \t\r\n]+)
#error{ $"Unexpected '{Regex.Escape(unexpected)}' at line {state.Line}, col {state.Column - 1}" }
Make use of the stateful parsing.
@using System.Linq
@members
{
private static void AddError(Cursor state, string message)
{
var existing = state["errors"] as IList<MyError>;
var newList = existing == null ? new List<MyError>() : existing.ToList();
newList.Add(new MyError
{
Line = state.Line,
Column = state.Column,
Message = message,
});
state["errors"] = newList.AsReadOnly();
}
}
start<MyResult>
= stuff:stuff { new MyResult { Stuff = stuff, Errors = state["errors"] } }
stuff
= foo:("foo" / "bar") #{ AddError(state, "An error occured: " + foo); }
You can use the -export
flag to make a rule visible in a grammar's exported rules collection:
@namespace PegExamples
@classname Library
Expression <YourType> -export = 'OK' { new YourType() }
This can then be used from another parser like so:
@namespace PegExamples
@classname Consumer
@members
{
private readonly Library library = new Library();
}
delimitedExpression <YourType> = '{' x:importedExpression '}' { x }
importedExpression <YourType> = #parse{ this.library.Exported.Expression(ref state) }