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