mirror of
https://github.com/fluencelabs/lalrpop
synced 2025-03-16 17:00:53 +00:00
Merge pull request #293 from ahmedcharles/pubrestricted
Add support for pub(restricted).
This commit is contained in:
commit
50fb8a5d74
@ -1,6 +1,6 @@
|
||||
language: rust
|
||||
rust:
|
||||
- 1.16.0
|
||||
- 1.18.0
|
||||
- beta
|
||||
- nightly
|
||||
script:
|
||||
|
@ -15,7 +15,7 @@ extern {
|
||||
}
|
||||
}
|
||||
|
||||
pub Expr = {
|
||||
pub(crate) Expr = {
|
||||
<l:Expr> "-" <r:Factor> => l - r,
|
||||
<l:Expr> "+" <r:Factor> => l + r,
|
||||
Factor,
|
||||
|
@ -396,7 +396,8 @@ fn emit_recursive_ascent(session: &Session, grammar: &r::Grammar, report_file :
|
||||
}
|
||||
|
||||
rust!(rust,
|
||||
"pub use self::{}parse{}::parse_{};",
|
||||
"{}use self::{}parse{}::parse_{};",
|
||||
grammar.nonterminals[&user_nt].visibility,
|
||||
grammar.prefix,
|
||||
start_nt,
|
||||
user_nt);
|
||||
|
@ -342,10 +342,24 @@ pub struct Parameter {
|
||||
pub ty: TypeRef,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum Visibility {
|
||||
Pub(Option<Path>),
|
||||
Priv,
|
||||
}
|
||||
|
||||
impl Visibility {
|
||||
pub fn is_pub(&self) -> bool {
|
||||
match *self {
|
||||
Visibility::Pub(_) => true,
|
||||
Visibility::Priv => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct NonterminalData {
|
||||
// a "public" nonterminal is one that we will use as a start symbol
|
||||
pub public: bool,
|
||||
pub visibility: Visibility,
|
||||
pub name: NonterminalString,
|
||||
pub annotations: Vec<Annotation>,
|
||||
pub span: Span,
|
||||
@ -646,6 +660,16 @@ impl Symbol {
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Visibility {
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
|
||||
match *self {
|
||||
Visibility::Pub(Some(ref path)) => write!(fmt, "pub({}) ", path),
|
||||
Visibility::Pub(None) => write!(fmt, "pub "),
|
||||
Visibility::Priv => Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Display> Display for WhereClause<T> {
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
|
||||
match *self {
|
||||
|
@ -17,7 +17,11 @@ pub use grammar::parse_tree::{Annotation,
|
||||
NonterminalString,
|
||||
Path,
|
||||
Span,
|
||||
TerminalLiteral, TerminalString, TypeParameter, WhereClause};
|
||||
TerminalLiteral,
|
||||
TerminalString,
|
||||
TypeParameter,
|
||||
Visibility,
|
||||
WhereClause};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Grammar {
|
||||
@ -75,6 +79,7 @@ pub struct TerminalSet {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct NonterminalData {
|
||||
pub name: NonterminalString,
|
||||
pub visibility: Visibility,
|
||||
pub span: Span,
|
||||
pub annotations: Vec<Annotation>,
|
||||
pub productions: Vec<Production>,
|
||||
|
@ -135,6 +135,7 @@ impl<'codegen, 'grammar, W: Write, C> CodeGenerator<'codegen, 'grammar, W, C> {
|
||||
|
||||
rust!(self.out, "#[allow(dead_code)]");
|
||||
try!(self.out.write_pub_fn_header(self.grammar,
|
||||
&self.grammar.nonterminals[&self.start_symbol].visibility,
|
||||
format!("parse_{}", self.user_start_symbol),
|
||||
type_parameters,
|
||||
parameters,
|
||||
|
@ -3,6 +3,7 @@
|
||||
use collections::{Map, Set};
|
||||
use grammar::parse_tree::WhereClause;
|
||||
use grammar::repr::*;
|
||||
use intern::intern;
|
||||
use lr1::core::*;
|
||||
use lr1::lookahead::Token;
|
||||
use rust::RustWrite;
|
||||
@ -749,6 +750,7 @@ impl<'ascent, 'grammar, W: Write> CodeGenerator<'ascent, 'grammar, W, TableDrive
|
||||
format!("_: {}", self.phantom_data_type())];
|
||||
|
||||
try!(self.out.write_pub_fn_header(self.grammar,
|
||||
&Visibility::Pub(Some(Path::from_id(intern("crate")))),
|
||||
format!("{}reduce", self.prefix),
|
||||
vec![],
|
||||
parameters,
|
||||
|
@ -54,11 +54,12 @@ impl<'ascent, 'grammar, W: Write> CodeGenerator<'ascent, 'grammar, W, TestAll> {
|
||||
this.states,
|
||||
"super::super::super",
|
||||
this.out));
|
||||
rust!(this.out,
|
||||
"pub use self::{}parse{}::parse_{};",
|
||||
this.prefix,
|
||||
this.start_symbol,
|
||||
this.user_start_symbol);
|
||||
let pub_use = format!("{}use self::{}parse{}::parse_{};",
|
||||
this.grammar.nonterminals[&this.user_start_symbol].visibility,
|
||||
this.prefix,
|
||||
this.start_symbol,
|
||||
this.user_start_symbol);
|
||||
rust!(this.out, "{}", pub_use);
|
||||
rust!(this.out, "}}");
|
||||
|
||||
rust!(this.out, "mod {}parse_table {{", this.prefix);
|
||||
@ -68,11 +69,7 @@ impl<'ascent, 'grammar, W: Write> CodeGenerator<'ascent, 'grammar, W, TestAll> {
|
||||
this.states,
|
||||
"super::super::super",
|
||||
this.out));
|
||||
rust!(this.out,
|
||||
"pub use self::{}parse{}::parse_{};",
|
||||
this.prefix,
|
||||
this.start_symbol,
|
||||
this.user_start_symbol);
|
||||
rust!(this.out, "{}", pub_use);
|
||||
rust!(this.out, "}}");
|
||||
|
||||
Ok(())
|
||||
|
@ -137,6 +137,7 @@ impl<'s> LowerState<'s> {
|
||||
self.nonterminals.insert(nt_name,
|
||||
r::NonterminalData {
|
||||
name: nt_name,
|
||||
visibility: nt.visibility.clone(),
|
||||
annotations: nt.annotations,
|
||||
span: nt.span,
|
||||
productions: productions,
|
||||
@ -215,7 +216,7 @@ impl<'s> LowerState<'s> {
|
||||
grammar.items
|
||||
.iter()
|
||||
.filter_map(|item| item.as_nonterminal())
|
||||
.filter(|nt| nt.public)
|
||||
.filter(|nt| nt.visibility.is_pub())
|
||||
.map(|nt| {
|
||||
// create a synthetic symbol `__Foo` for each public symbol `Foo`
|
||||
// with a rule like:
|
||||
@ -241,6 +242,7 @@ impl<'s> LowerState<'s> {
|
||||
self.nonterminals.insert(fake_name,
|
||||
r::NonterminalData {
|
||||
name: fake_name,
|
||||
visibility: nt.visibility.clone(),
|
||||
annotations: vec![],
|
||||
span: nt.span,
|
||||
productions: vec![production],
|
||||
|
@ -10,7 +10,8 @@ use grammar::parse_tree::{ActionKind, Alternative, Annotation,
|
||||
Path,
|
||||
RepeatOp, RepeatSymbol,
|
||||
Span, Symbol, SymbolKind,
|
||||
TerminalLiteral, TerminalString, TypeRef};
|
||||
TerminalLiteral, TerminalString, TypeRef,
|
||||
Visibility};
|
||||
use normalize::resolve;
|
||||
use normalize::{NormResult, NormError};
|
||||
use normalize::norm_util::{self, Symbols};
|
||||
@ -198,7 +199,7 @@ impl MacroExpander {
|
||||
}
|
||||
|
||||
Ok(GrammarItem::Nonterminal(NonterminalData {
|
||||
public: mdef.public,
|
||||
visibility: mdef.visibility.clone(),
|
||||
span: span,
|
||||
name: msym_name,
|
||||
annotations: mdef.annotations.clone(),
|
||||
@ -363,7 +364,7 @@ impl MacroExpander {
|
||||
};
|
||||
|
||||
Ok(GrammarItem::Nonterminal(NonterminalData {
|
||||
public: false,
|
||||
visibility: Visibility::Priv,
|
||||
span: span,
|
||||
name: name,
|
||||
annotations: inline(span),
|
||||
@ -397,7 +398,7 @@ impl MacroExpander {
|
||||
});
|
||||
|
||||
Ok(GrammarItem::Nonterminal(NonterminalData {
|
||||
public: false,
|
||||
visibility: Visibility::Priv,
|
||||
span: span,
|
||||
name: name,
|
||||
annotations: inline(span),
|
||||
@ -436,7 +437,7 @@ impl MacroExpander {
|
||||
let ty_ref = TypeRef::Nominal { path: path, types: vec![base_symbol_ty] };
|
||||
|
||||
Ok(GrammarItem::Nonterminal(NonterminalData {
|
||||
public: false,
|
||||
visibility: Visibility::Priv,
|
||||
span: span,
|
||||
name: name,
|
||||
annotations: vec![],
|
||||
@ -475,7 +476,7 @@ impl MacroExpander {
|
||||
let ty_ref = TypeRef::Nominal { path: path, types: vec![base_symbol_ty] };
|
||||
|
||||
Ok(GrammarItem::Nonterminal(NonterminalData {
|
||||
public: false,
|
||||
visibility: Visibility::Priv,
|
||||
span: span,
|
||||
name: name,
|
||||
annotations: inline(span),
|
||||
@ -506,7 +507,7 @@ impl MacroExpander {
|
||||
-> NormResult<GrammarItem> {
|
||||
let name = NonterminalString(intern(name));
|
||||
Ok(GrammarItem::Nonterminal(NonterminalData {
|
||||
public: false,
|
||||
visibility: Visibility::Priv,
|
||||
span: span,
|
||||
name: name,
|
||||
annotations: inline(span),
|
||||
|
@ -124,7 +124,7 @@ impl<'grammar> Validator<'grammar> {
|
||||
}
|
||||
}
|
||||
GrammarItem::Nonterminal(ref data) => {
|
||||
if data.public && !data.args.is_empty() {
|
||||
if data.visibility.is_pub() && !data.args.is_empty() {
|
||||
return_err!(data.span, "macros cannot be marked public");
|
||||
}
|
||||
let inline_annotation = intern(INLINE);
|
||||
@ -139,7 +139,7 @@ impl<'grammar> Validator<'grammar> {
|
||||
return_err!(annotation.id_span,
|
||||
"duplicate annotation `{}`",
|
||||
annotation.id);
|
||||
} else if annotation.id == inline_annotation && data.public {
|
||||
} else if annotation.id == inline_annotation && data.visibility.is_pub() {
|
||||
return_err!(annotation.id_span,
|
||||
"public items cannot be marked #[inline]");
|
||||
}
|
||||
|
@ -93,11 +93,17 @@ GrammarItem: GrammarItem = {
|
||||
Use: GrammarItem =
|
||||
<u:"use"> ";" => GrammarItem::Use(strip(u).to_string());
|
||||
|
||||
Visibility: Visibility = {
|
||||
"pub" "(" <p:Path> ")" => Visibility::Pub(Some(p)),
|
||||
"pub" => Visibility::Pub(None),
|
||||
() => Visibility::Priv,
|
||||
};
|
||||
|
||||
Nonterminal: GrammarItem =
|
||||
<annotations:Annotation*>
|
||||
<p:"pub"?> <lo:@L> <n:NonterminalName> <hi:@R>
|
||||
<v:Visibility> <lo:@L> <n:NonterminalName> <hi:@R>
|
||||
<t:(":" <TypeRef>)?> "=" <a:Alternatives> => {
|
||||
GrammarItem::Nonterminal(NonterminalData { public: p.is_some(),
|
||||
GrammarItem::Nonterminal(NonterminalData { visibility: v,
|
||||
span: Span(lo, hi),
|
||||
name: n.0,
|
||||
annotations: annotations,
|
||||
|
@ -2,6 +2,7 @@
|
||||
//! which then gets serialized.
|
||||
|
||||
use grammar::repr::Grammar;
|
||||
use grammar::parse_tree::Visibility;
|
||||
use tls::Tls;
|
||||
use std::fmt;
|
||||
use std::io::{self, Write};
|
||||
@ -106,6 +107,7 @@ impl<W:Write> RustWrite<W> {
|
||||
|
||||
pub fn write_pub_fn_header(&mut self,
|
||||
grammar: &Grammar,
|
||||
visibility: &Visibility,
|
||||
name: String,
|
||||
type_parameters: Vec<String>,
|
||||
parameters: Vec<String>,
|
||||
@ -113,7 +115,7 @@ impl<W:Write> RustWrite<W> {
|
||||
where_clauses: Vec<String>)
|
||||
-> io::Result<()>
|
||||
{
|
||||
self.write_fn_header_helper(grammar, "pub ", name, type_parameters,
|
||||
self.write_fn_header_helper(grammar, visibility, name, type_parameters,
|
||||
parameters, return_type, where_clauses)
|
||||
}
|
||||
|
||||
@ -126,13 +128,13 @@ impl<W:Write> RustWrite<W> {
|
||||
where_clauses: Vec<String>)
|
||||
-> io::Result<()>
|
||||
{
|
||||
self.write_fn_header_helper(grammar, "", name, type_parameters,
|
||||
self.write_fn_header_helper(grammar, &Visibility::Priv, name, type_parameters,
|
||||
parameters, return_type, where_clauses)
|
||||
}
|
||||
|
||||
fn write_fn_header_helper(&mut self,
|
||||
grammar: &Grammar,
|
||||
qualifiers: &str,
|
||||
visibility: &Visibility,
|
||||
name: String,
|
||||
type_parameters: Vec<String>,
|
||||
parameters: Vec<String>,
|
||||
@ -140,7 +142,7 @@ impl<W:Write> RustWrite<W> {
|
||||
where_clauses: Vec<String>)
|
||||
-> io::Result<()>
|
||||
{
|
||||
rust!(self, "{}fn {}<", qualifiers, name);
|
||||
rust!(self, "{}fn {}<", visibility, name);
|
||||
|
||||
for type_parameter in &grammar.type_parameters {
|
||||
rust!(self, "{0:1$}{2},", "", TAB, type_parameter);
|
||||
|
Loading…
x
Reference in New Issue
Block a user