Research-Stack/2-Search-Space/search/stract/crates/optics/src/parser.lalrpop

112 lines
No EOL
3.5 KiB
Text

use crate::ast::*;
use crate::lexer::Token;
use lalrpop_util::ParseError;
grammar<'input>;
Sep<S, T>: Vec<T> = {
<mut v:(<T> S)*> <e:T?> => match e {
None => v,
Some(e) => {
v.push(e);
v
}
}
};
pub Blocks: Vec<RawOpticBlock> = <Sep<";", Block>>;
Block: RawOpticBlock = {
<Rule> => RawOpticBlock::Rule(<>),
<HostPreference> => RawOpticBlock::HostPreference(<>),
"DiscardNonMatching" => RawOpticBlock::DiscardNonMatching,
}
Rule: RawRule = {
"Rule" "{" <matches:Sep<",", RawMatchBlock>> <action:RawAction?> "}" => RawRule {
matches,
action
}
}
RawMatchBlock: RawMatchBlock = {
"Matches" "{" <Sep<",", RawMatchPart>> "}" => RawMatchBlock(<>)
}
RawMatchPart: RawMatchPart = {
"Site" "(" <StringLiteral> ")" => RawMatchPart::Site(<>.to_string()),
"Url" "(" <StringLiteral> ")" => RawMatchPart::Url(<>.to_string()),
"Domain" "(" <StringLiteral> ")" => RawMatchPart::Domain(<>.to_string()),
"Title" "(" <StringLiteral> ")" => RawMatchPart::Title(<>.to_string()),
"Description" "(" <StringLiteral> ")" => RawMatchPart::Description(<>.to_string()),
"Content" "(" <StringLiteral> ")" => RawMatchPart::Content(<>.to_string()),
"MicroformatTag" "(" <StringLiteral> ")" => RawMatchPart::MicroformatTag(<>.to_string()),
"Schema" "(" <StringLiteral> ")" => RawMatchPart::Schema(<>.to_string()),
}
RawAction: RawAction= {
"Action" "(" <InnerAction> ")" => <>
}
InnerAction: RawAction= {
"Boost" "(" <l:@L> <value:Number> <r:@R> ")" =>? {
match value.parse() {
Ok(n) => Ok(RawAction::Boost(n)),
Err(_) => Err(ParseError::User {
error: crate::Error::NumberParse{ token: (l, value.to_string(), r)}
})
}
},
"Downrank" "(" <l:@L> <value:Number> <r:@R> ")" =>? {
match value.parse() {
Ok(n) => Ok(RawAction::Downrank(n)),
Err(_) => Err(ParseError::User {
error: crate::Error::NumberParse{ token: (l, value.to_string(), r)}
})
}
},
"Discard" => RawAction::Discard,
}
HostPreference: RawHostPreference = {
"Like" "(" "Site" "(" <StringLiteral> ")" ")" => RawHostPreference::Like(<>.to_string()),
"Dislike" "(" "Site" "(" <StringLiteral> ")" ")" => RawHostPreference::Dislike(<>.to_string())
}
extern {
type Location = usize;
type Error = crate::Error;
enum Token<'input> {
";" => Token::SemiColon,
"," => Token::Comma,
"{" => Token::OpenBracket,
"}" => Token::CloseBracket,
"(" => Token::OpenParenthesis,
")" => Token::CloseParenthesis,
"DiscardNonMatching" => Token::DiscardNonMatching,
"Rule" => Token::Rule,
"Stage" => Token::Stage,
"Signal" => Token::Signal,
"Field" => Token::Field,
"Matches" => Token::Matches,
"Site" => Token::Site,
"Url" => Token::Url,
"Domain" => Token::Domain,
"Title" => Token::Title,
"Description" => Token::Description,
"Content" => Token::Content,
"MicroformatTag" => Token::MicroformatTag,
"Schema" => Token::Schema,
"Action" => Token::Action,
"Boost" => Token::Boost,
"Downrank" => Token::Downrank,
"Discard" => Token::Discard,
"Like" => Token::Like,
"Dislike" => Token::Dislike,
StringLiteral => Token::String(<&'input str>),
Number => Token::Number(<&'input str>),
}
}