Merge pull request #353 from ayosec/outdir-280

Generate files in OUT_DIR
This commit is contained in:
Markus Westerlind 2018-06-05 10:54:47 +02:00 committed by GitHub
commit 5766e5f3c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 137 additions and 122 deletions

47
.gitignore vendored
View File

@ -2,50 +2,3 @@ target
*~
TAGS
lalrpop/src/parser/lrgrammar.rs
doc/calculator/src/calculator1.rs
doc/calculator/src/calculator2.rs
doc/calculator/src/calculator2b.rs
doc/calculator/src/calculator3.rs
doc/calculator/src/calculator4.rs
doc/calculator/src/calculator5.rs
doc/calculator/src/calculator6.rs
doc/pascal/lalrpop/src/pascal.rs
doc/whitespace/src/parser.rs
lalrpop-test/src/error.rs
lalrpop-test/src/error_issue_113.rs
lalrpop-test/src/error_issue_278.rs
lalrpop-test/src/error_issue_261.rs
lalrpop-test/src/error_recovery.rs
lalrpop-test/src/error_recovery_pull_182.rs
lalrpop-test/src/error_recovery_issue_240.rs
lalrpop-test/src/error_recovery_lock_in.rs
lalrpop-test/src/error_recovery_lalr_loop.rs
lalrpop-test/src/error_recovery_span.rs
lalrpop-test/src/error_recovery_type_in_macro.rs
lalrpop-test/src/expr.rs
lalrpop-test/src/expr_arena.rs
lalrpop-test/src/expr_generic.rs
lalrpop-test/src/expr_intern_tok.rs
lalrpop-test/src/expr_lalr.rs
lalrpop-test/src/expr_module_attributes.rs
lalrpop-test/src/generics_issue_104.rs
lalrpop-test/src/inline.rs
lalrpop-test/src/intern_tok.rs
lalrpop-test/src/issue_55.rs
lalrpop-test/src/lifetime_tok.rs
lalrpop-test/src/loc.rs
lalrpop-test/src/loc_issue_90.rs
lalrpop-test/src/sub.rs
lalrpop-test/src/sub_ascent.rs
lalrpop-test/src/sub_table.rs
lalrpop-test/src/unit.rs
lalrpop-test/src/use_super.rs
lalrpop-test/src/no_clone_tok.rs
lalrpop-test/src/partial_parse.rs
lalrpop-test/src/match_alternatives.rs
lalrpop-test/src/match_section.rs
lalrpop-test/src/expr_module_attributes.rs
lalrpop-test/src/associated_types.rs
lalrpop-test/src/where_clause_with_forall.rs

View File

@ -1,6 +1,6 @@
extern crate lalrpop_util;
#[macro_use] extern crate lalrpop_util;
pub mod calculator1; // synthesized by LALRPOP
lalrpop_mod!(pub calculator1); // syntesized by LALRPOP
#[test]
fn calculator1() {
@ -10,7 +10,7 @@ fn calculator1() {
assert!(calculator1::TermParser::new().parse("((22)").is_err());
}
pub mod calculator2;
lalrpop_mod!(pub calculator2);
#[test]
fn calculator2() {
@ -20,7 +20,7 @@ fn calculator2() {
assert!(calculator2::TermParser::new().parse("((22)").is_err());
}
pub mod calculator2b;
lalrpop_mod!(pub calculator2b);
#[test]
fn calculator2b() {
@ -37,7 +37,7 @@ fn calculator2b() {
assert_eq!(result, "222");
}
pub mod calculator3;
lalrpop_mod!(pub calculator3);
#[cfg_attr(not(test), allow(unused_macros))]
macro_rules! test3 {
@ -56,7 +56,7 @@ fn calculator3() {
test3!(22 * (44 + 66) / 3);
}
pub mod calculator4;
lalrpop_mod!(pub calculator4);
pub mod ast;
#[test]
@ -67,7 +67,7 @@ fn calculator4() {
assert_eq!(&format!("{:?}", expr), "((22 * 44) + 66)");
}
pub mod calculator5;
lalrpop_mod!(pub calculator5);
#[test]
fn calculator5() {
@ -95,7 +95,7 @@ fn calculator5() {
assert_eq!(&format!("{:?}", expr), "[((22 * 44) + 66), (13 * 3)]");
}
pub mod calculator6;
lalrpop_mod!(pub calculator6);
#[test]
fn calculator6() {

View File

@ -3,7 +3,6 @@ extern crate lalrpop;
fn main() {
lalrpop::Configuration::new()
.emit_comments(true)
.use_cargo_dir_conventions()
.process_current_dir()
.unwrap();
}

View File

@ -2,6 +2,7 @@ extern crate docopt;
#[macro_use]
extern crate serde_derive;
extern crate serde;
#[macro_use] extern crate lalrpop_util;
use docopt::Docopt;
use std::env;
@ -9,7 +10,7 @@ use std::io::Read;
use std::fs::File;
use std::time::Instant;
mod pascal;
lalrpop_mod!(pascal);
fn main() {
let args: Args = Docopt::new(USAGE)

View File

@ -14,6 +14,6 @@
- [Error recovery](tutorial/008_error_recovery.md)
- [Writing a custom lexer](lexer_tutorial/index.md)
- [Advanced setup](advanced_setup.md)
- [Using the Cargo `OUT_DIR`](out_dir.md)
- [Generate in source tree](generate_in_source.md)
-----------
[Contributors](misc/contributors.md)

View File

@ -0,0 +1,19 @@
Up to version 0.15, LALRPOP was generating its files in the same directory
of the input files. Since 0.16, files are generated in the Cargo's
**output directory**.
If you want to keep the previous behaviour, you can use `generate_in_source_tree`
in your configuration:
```rust
extern crate lalrpop;
fn main() {
lalrpop::Configuration::new()
.generate_in_source_tree()
.process();
}
```
For each `foo.lalrpop` file you can simply have `mod foo;` in your source tree.
The `lalrpop_mod` macro is not useful in this mode.

View File

@ -1,24 +0,0 @@
One common request is to have LALRPOP generate its files into Cargo's
**output directory**, rather than storing them 'in-place' within the
module tree. This can be done through the following configuration:
```rust
extern crate lalrpop;
fn main() {
lalrpop::Configuration::new()
.use_cargo_dir_conventions()
.process();
}
```
In addition, because the modules are generated out of the `src`
directory, for each `foo.lalrpop` file you can't simply have `mod
foo;` in your source. Instead, you must put the following in the
parent module:
```rust
include!(concat!(env!("OUT_DIR"), "/path/to/foo.rs"));
```
Here the `path/to/foo.rs` should be relative to the `src` directory.

View File

@ -101,7 +101,9 @@ our [`main.rs`][main] file which uses this struct to test our `Term`
nonterminal:
```rust
pub mod calculator1; // synthesized by LALRPOP
#[macro_use] extern crate lalrpop_util;
lalrpop_mod!(pub calculator1); // synthesized by LALRPOP
#[test]
fn calculator1() {

View File

@ -103,7 +103,9 @@ FactorOp: Opcode = {
And, of course, we have to add some tests to [main.rs file][main]:
```rust
pub mod calculator5;
#[macro_use] extern crate lalrpop_util;
lalrpop_mod!(pub calculator5);
#[test]
fn calculator5() {

View File

@ -1,8 +1,11 @@
#[macro_use] extern crate lalrpop_util;
pub mod lexer;
pub mod parser;
pub mod ast;
pub mod eval;
lalrpop_mod!(pub parser);
pub fn compile(input: &str) -> Result<ast::Program, String> {
match parser::ProgramParser::new().parse(lexer::Lexer::new(input)) {
Ok(s) => Ok(ast::Program::new(s)),

View File

@ -1,4 +1,3 @@
#![cfg_attr(feature = "cargo-clippy", allow(clippy))]
grammar(scale: i32);
use util::tok::Tok;

View File

@ -1,7 +1,7 @@
#![cfg_attr(not(test), allow(dead_code, unused_imports))]
extern crate diff;
extern crate lalrpop_util;
#[macro_use] extern crate lalrpop_util;
use std::cell::RefCell;
@ -11,105 +11,105 @@ use util::tok::Tok;
/// Tests that actions can return the grammar's type parameters' associated
/// types.
mod associated_types;
lalrpop_mod!(associated_types);
mod associated_types_lib;
/// demonstration from the Greene text; one of the simplest grammars
/// that still ensures we get parse tree correct
mod sub;
lalrpop_mod!(sub);
/// test something other than test-all
mod sub_ascent;
mod sub_table;
lalrpop_mod!(sub_ascent);
lalrpop_mod!(sub_table);
/// more interesting demonstration of parsing full expressions
mod expr;
lalrpop_mod!(expr);
/// more interesting demonstration of parsing full expressions, using LALR not LR
mod expr_lalr;
lalrpop_mod!(expr_lalr);
/// more interesting demonstration of parsing full expressions, using intern tok
mod expr_intern_tok;
lalrpop_mod!(expr_intern_tok);
/// tests #![attributes] for generated module
#[allow(dead_code, unknown_lints)]
mod expr_module_attributes;
lalrpop_mod!(expr_module_attributes);
/// test that passes in lifetime/type/formal parameters and threads
/// them through, building an AST from the result
mod expr_arena;
lalrpop_mod!(expr_arena);
/// definitions of the AST
mod expr_arena_ast;
/// expr defined with a generic type `F`
mod expr_generic;
lalrpop_mod!(expr_generic);
mod generics_issue_104;
lalrpop_mod!(generics_issue_104);
mod generics_issue_104_lib;
/// Grammar parameterized by `F` with where clause `where F: for<'a> FnMut(&'a
/// str)`.
mod where_clause_with_forall;
lalrpop_mod!(where_clause_with_forall);
/// test of inlining
mod inline;
lalrpop_mod!(inline);
/// test that exercises internal token generation, as well as locations and spans
mod intern_tok;
lalrpop_mod!(intern_tok);
/// test that exercises using a lifetime parameter in the token type
mod lifetime_tok;
lalrpop_mod!(lifetime_tok);
/// library for lifetime_tok test
mod lifetime_tok_lib;
/// test that exercises locations and spans
mod loc;
lalrpop_mod!(loc);
/// regression test for location issue #90
mod loc_issue_90;
lalrpop_mod!(loc_issue_90);
mod loc_issue_90_lib;
/// test that uses `super` in paths in various places
mod use_super;
lalrpop_mod!(use_super);
/// Custom error type (issue #113)
#[derive(Debug, PartialEq)]
pub struct MyCustomError(char);
/// test that exercises locations, spans, and custom errors
mod error;
mod error_issue_113;
lalrpop_mod!(error);
lalrpop_mod!(error_issue_113);
/// Test error recovery
mod error_recovery;
mod error_recovery_pull_182;
mod error_recovery_issue_240;
mod error_recovery_lalr_loop;
mod error_recovery_lock_in;
mod error_recovery_span;
mod error_recovery_type_in_macro;
lalrpop_mod!(error_recovery);
lalrpop_mod!(error_recovery_pull_182);
lalrpop_mod!(error_recovery_issue_240);
lalrpop_mod!(error_recovery_lalr_loop);
lalrpop_mod!(error_recovery_lock_in);
lalrpop_mod!(error_recovery_span);
lalrpop_mod!(error_recovery_type_in_macro);
/// test for inlining expansion issue #55
mod issue_55;
lalrpop_mod!(issue_55);
/// test for unit action code
mod unit;
lalrpop_mod!(unit);
/// test for match section
mod match_section;
mod match_alternatives;
lalrpop_mod!(match_section);
lalrpop_mod!(match_alternatives);
/// regression test for issue #253.
mod partial_parse;
lalrpop_mod!(partial_parse);
/// regression test for issue #278.
mod error_issue_278;
lalrpop_mod!(error_issue_278);
// Check that error recovery (which requires cloneable tokens) is not created if it is not used
#[allow(unused)]
mod no_clone_tok;
lalrpop_mod!(no_clone_tok);
mod util;

View File

@ -143,6 +143,35 @@ pub struct ErrorRecovery<L, T, E> {
pub dropped_tokens: Vec<(L, T, L)>,
}
/// Define a module using the generated parse from a `.lalrpop` file.
///
/// You have to specify the name of the module and the path of the file
/// generated by LALRPOP. If the input is in the root directory, you can
/// omit it.
///
/// # Example
/// ```ignore
/// // load parser in src/parser.lalrpop
/// lalrpop_mod!(parser);
///
/// // load parser in src/lex/parser.lalrpop
/// lalrpop_mod!(parser, "/lex/parser.rs");
///
/// // define a public module
/// lalrpop_mod!(pub parser);
/// ```
#[macro_export]
macro_rules! lalrpop_mod {
($modname:ident) => { lalrpop_mod!($modname, concat!("/", stringify!($modname), ".rs")); };
(pub $modname:ident) => { lalrpop_mod!(pub $modname, concat!("/", stringify!($modname), ".rs")); };
($modname:ident, $source:expr) => { mod $modname { include!(concat!(env!("OUT_DIR"), $source)); } };
(pub $modname:ident, $source:expr) => { pub mod $modname { include!(concat!(env!("OUT_DIR"), $source)); } };
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -76,6 +76,20 @@ impl Configuration {
self
}
/// Write output files in the same directory of the input files.
///
/// If this option is enabled, you have to load the parser as a module:
///
/// ```no_run
/// mod parser; // synthesized from parser.lalrpop
/// ```
///
/// This was the default behaviour up to version 0.15.
pub fn generate_in_source_tree(&mut self) -> &mut Self {
self.set_in_dir(Path::new("."))
.set_out_dir(Path::new("."))
}
/// If true, always convert `.lalrpop` files into `.rs` files, even if the
/// `.rs` file is newer. Default is false.
pub fn force_build(&mut self, val: bool) -> &mut Configuration {
@ -149,7 +163,25 @@ impl Configuration {
/// Process all `.lalrpop` files in `path`.
pub fn process_dir<P: AsRef<Path>>(&self, path: P) -> Result<(), Box<Error>> {
let session = Rc::new(self.session.clone());
let mut session = self.session.clone();
// If in/out dir are empty, use cargo conventions by default.
// See https://github.com/lalrpop/lalrpop/issues/280
if session.in_dir.is_none() {
let mut in_dir = try!(env::current_dir());
in_dir.push("src");
session.in_dir = Some(in_dir);
}
if session.out_dir.is_none() {
let out_dir = match env::var_os("OUT_DIR") {
Some(var) => var,
None => return Err("missing OUT_DIR variable")?,
};
session.out_dir = Some(PathBuf::from(out_dir));
}
let session = Rc::new(session);
try!(build::process_dir(session, path));
Ok(())
}